我正在使用Apache Ignite docker容器,我想使用C ++将数据写入缓存,然后在Python中使用Pyignite对其进行访问。我已经能够使用Apache Ignite C ++瘦客户端将键-值对添加到C ++中的缓存中,然后如果它们的键和值在两种语言中都是可识别的类型,则可以使用Pyignite从Python读取它们。 int,float,string等。我想创建键-值对,其中键是std :: string,值是std :: map,但是我无法在C ++中使用它,所以我决定按照here的说明创建包含std :: map的C ++结构。我可以在C ++中将键值对获取/放入高速缓存,但是我无法使用Python来获取它们。
这是起作用的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;
}
};
这是我填充缓存的方法:
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);
这是我要开始工作的内容,但无法在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)
我认为我的问题是我如何尝试在Python中访问缓存。如果该值是整数,浮点数,字符串或内置值,那么我可以在Python中执行cache.get(key)
并且它可以工作。而且由于C ++代码可同时用于cache.Get
和cache.Put
(在C ++中),所以我认为这是在两种语言之间切换的必要条件。
有人知道我做错了什么,或者我需要如何修改C ++结构或如何在Python中定义二进制类型?
我不确定为什么会挂起,但是尝试使用客户端的compact_footer
参数,C ++节点可能需要它。
您也可以在节点的控制台日志中扫描线索。
作为旁注,您不必在这里注册任何类型。仅my_cache.get(key)
就足够了。