简体   繁体   English

Apache 点燃 C++ 结构到 Pyignite object 不工作

[英]Apache Ignite C++ struct to Pyignite object not working

I am using an Apache Ignite docker container and I want to write data to the cache using C++ and then access it using Pyignite in Python. I am using an Apache Ignite docker container and I want to write data to the cache using C++ and then access it using Pyignite in Python. I have been able to add key-value pairs to the cache in C++ using the Apache Ignite C++ Thin Client and then read them from Python using Pyignite if they key and value are recognized types in both languages, eg int, float, string, etc. I want to create key-value pairs where the key is a std::string and the value is a std::map, but I couldn't get that to work in C++, so I decided to follow the directions here to create my C++ struct containing a std::map. I have been able to add key-value pairs to the cache in C++ using the Apache Ignite C++ Thin Client and then read them from Python using Pyignite if they key and value are recognized types in both languages, eg int, float, string, etc . 我想创建键值对,其中键是 std::string,值是 std::map,但我无法在 C++ 中使用它,所以我决定按照此处的说明创建我的 C++ 结构包含一个 std::map。 I can get/put key-value pairs into the cache in C++, but I haven't been able to get them using Python.我可以将键值对获取/放入 C++ 的缓存中,但我无法使用 Python 获取它们。

Here's the C++ struct that works:这是有效的 C++ 结构:

#include <stdio.h>
#include <stdlib.h>
#include <string>

#include <ignite/binary/binary.h>
#include <ignite/thin/ignite_client.h>
#include <ignite/thin/cache/cache_client.h>

using namespace ignite;
using namespace thin;
using namespace cache;


class MyMap
{
  friend struct binary::BinaryType<MyMap>;
public:
  MyMap() { }

  MyMap(std::map<std::string, float> mp) :
  mp(mp) { }

  std::map<std::string, float> GetMap() const
  {
    return mp;
  }

  std::string ToString()
  {
    std::ostringstream oss;

    for(std::map<std::string, float>::const_iterator it = mp.begin();
    it != mp.end(); ++it)
      {
    oss << it->first << ": " << it->second << "\n";
      }
    return oss.str();
  }
  std::map<std::string, float> mp;
};
typedef struct MyMap MyMap;

template<>
struct binary::BinaryType<MyMap>
{

  static int32_t GetTypeId()
  {
    return GetBinaryStringHashCode("MyMap");
  }

  static void GetTypeName(std::string& name)
  {
    name = "MyMap";
  }

  static int32_t GetFieldId(const char* name)
  {
    return GetBinaryStringHashCode(name);
  }

  static bool IsNull(const MyMap& obj)
  {
    return obj.GetMap().empty();
  }

  static void GetNull(MyMap& mymap)
  {
    mymap = MyMap();
  }

  static void Write(BinaryWriter& writer, const MyMap& obj)
  {
    BinaryMapWriter<std::string, float> bmap_writer = writer.WriteMap<std::string, float>("mp");

    for(std::map<std::string, float>::const_iterator it = obj.mp.begin(); it != obj.mp.end(); ++it)
      {
    bmap_writer.Write(it->first, it->second);
      }

    bmap_writer.Close();
  }

  static void Read(BinaryReader& reader, MyMap& mymap)
  {
    BinaryMapReader<std::string, float> bmap_reader = reader.ReadMap<std::string, float>("mp");
    std::string key;
    float val;
    std::map<std::string, float> tmp_map;
    while (bmap_reader.HasNext()){
      bmap_reader.GetNext(key, val);
      tmp_map[key] = val;
    }
    mymap.mp = tmp_map;
  }
};

And here's how I populate the cache:这是我填充缓存的方式:

IgniteClientConfiguration cfg;
cfg.SetEndPoints("ignite_cache");
IgniteClient client = IgniteClient::Start(cfg);

CacheClient<std::string, MyMap> cache = client.GetOrCreateCache<std::string, MyMap>("ignite_cache");

std::string key("my_test_key");
std::map<std::string, float> data_map;
data_map["a"] = 1.0;
data_map["b"] = 2.5;
MyMap mymap (data_map);

cache.Put(key, mymap);

Here's what I'm trying to get working, but haven't been able to in Python:这是我正在尝试的工作,但无法在 Python 中进行:

import pyignite

client = pyignite.Client()
client.connect("ignite_cache", 10800)
my_cache = client.get_or_create_cache("ignite_cache")

key = "my_test_key"

# This returns True
my_cache.contains_key(key)

# I was unable to get pyignite.register_binary_type to work so I tried this
res = pyignite.api.binary.put_binary_type(client, "MyMap", schema={'mp': pyignite.datatypes.MapObject})
# res.message = 'Success'

# This is where it doesn't work - it doesn't break, it just hangs.
my_cache.get(key)

I think my issue is how I am trying to access the cache in Python.我认为我的问题是我如何尝试访问 Python 中的缓存。 If the value is an integer, float, string, or something built-in, then I can do cache.get(key) in Python and it works.如果该值是 integer、float、string 或内置的东西,那么我可以在cache.get(key)并且它可以工作。 And since the C++ code works for both cache.Get and cache.Put (in C++), I think it's something about going between the two languages.由于 C++ 代码适用于cache.Getcache.Put (在 C++ 中),我认为这是在两种语言之间进行切换。

Does anyone have an idea of what I'm doing wrong or how I need to modify either the C++ struct or how I define the binary type in Python?有谁知道我做错了什么或者我需要如何修改 C++ 结构或如何在 Python 中定义二进制类型?

I'm not sure why it hangs, but try playing around with the client's compact_footer parameter, it might be needed for C++ node.我不确定它为什么挂起,但尝试使用客户端的compact_footer参数,C++ 节点可能需要它。

You may also scan the node's console log for the clues.您还可以扫描节点的控制台日志以获取线索。

As a side note, you don't have to register any types here.作为旁注,您不必在此处注册任何类型。 Just my_cache.get(key) should be enough.只需my_cache.get(key)就足够了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM