我一直试图让我的点燃连续查询代码工作,而不用将对等类加载设置为启用。但是我发现代码不起作用。我尝试调试并意识到对cache.query(qry)的调用错误消息“无法编组自定义事件”错误。当我启用对等类加载时,代码按预期工作。有人可以提供如何在没有同伴类加载的情况下完成这项工作的指导吗? 以下是调用连续查询的代码段。
public void subscribeEvent(IgniteCache<String,String> cache,String inKeyStr,ServerWebSocket websocket ){
System.out.println("in thread "+Thread.currentThread().getId()+"-->"+"subscribe event");
//ArrayList<String> inKeys = new ArrayList<String>(Arrays.asList(inKeyStr.split(",")));
ContinuousQuery<String, String> qry = new ContinuousQuery<>();
/****
* Continuous Query Impl
*/
inKeys = ","+inKeyStr+",";
qry.setInitialQuery(new ScanQuery<String, String>((k, v) -> inKeys.contains(","+k+",")));
qry.setTimeInterval(1000);
qry.setPageSize(1);
// Callback that is called locally when update notifications are received.
// Factory<CacheEntryEventFilter<String, String>> rmtFilterFactory = new com.ccx.ignite.cqfilter.FilterFactory().init(inKeyStr);
qry.setLocalListener(new CacheEntryUpdatedListener<String, String>() {
@Override public void onUpdated(Iterable<CacheEntryEvent<? extends String, ? extends String>> evts) {
for (CacheEntryEvent<? extends String, ? extends String> e : evts)
{
System.out.println("websocket locallsnr data in thread "+Thread.currentThread().getId()+"-->"+"key=" + e.getKey() + ", val=" + e.getValue());
try{
websocket.writeTextMessage("key=" + e.getKey() + ", val=" + e.getValue());
}
catch (Exception e1){
System.out.println("exception local listener "+e1.getMessage());
qry.setLocalListener(null) ; }
}
}
} );
qry.setRemoteFilterFactory( new com.ccx.ignite.cqfilter.FilterFactory().init(inKeys));
try{
cur = cache.query(qry);
for (Cache.Entry<String, String> e : cur)
{
System.out.println("websocket initialqry data in thread "+Thread.currentThread().getId()+"-->"+"key=" + e.getKey() + ", val=" + e.getValue());
websocket.writeTextMessage("key=" + e.getKey() + ", val=" + e.getValue());
}
}
catch (Exception e){
System.out.println("exception cache.query "+e.getMessage());
}
}
以下是我在一个自包含的jar中创建的远程过滤器类,并将其推入了ignite的libs文件夹中,以便服务器节点可以选择这个类
public class FilterFactory
{
public Factory<CacheEntryEventFilter<String, String>> init(String inKeyStr ){
System.out.println("factory init called jun22 ");
return new Factory <CacheEntryEventFilter<String, String>>() {
private static final long serialVersionUID = 5906783589263492617L;
@Override public CacheEntryEventFilter<String, String> create() {
return new CacheEntryEventFilter<String, String>() {
@Override public boolean evaluate(CacheEntryEvent<? extends String, ? extends String> e) {
//List inKeys = new ArrayList<String>(Arrays.asList(inKeyStr.split(",")));
System.out.println("inside remote filter factory ");
String inKeys = ","+inKeyStr+",";
return inKeys.contains(","+e.getKey()+",");
}
};
}
};
}
}
我正在尝试实现的总体逻辑是让websocket客户端通过指定缓存名称和感兴趣的键来订阅事件。 调用订阅事件代码,该代码创建连续查询并为感兴趣的键上的任何更新事件注册本地侦听器回调。 远程过滤器应根据作为字符串传递给它的键过滤更新事件,并在过滤器事件成功时调用本地侦听器。本地侦听器将更新的键值写入传递给订阅事件代码的Web套接字引用。
使用的Ignite版本是1.8.0。但是2.0中的行为也是一样的。 非常感谢任何帮助!
以下是包含相关错误的日志片段
工厂初始化名为jun22 exception cache.query class org.apache.ignite.spi.IgniteSpiException:无法编组自定义事件:StartRoutineDiscoveryMessage [startReqData = StartRequestData [prjPred=org.apache.ignite.configuration.CacheConfiguration$IgniteAllNodesPredicate@269707de,clsName = null,depInfo = null ,hnd = CacheContinuousQueryHandlerV2 [rmtFilterFactory = com.ccx.ignite.cqfilter.FilterFactory$1@5dc301ed,rmtFilterFactoryDep = null,types = 0],bufSize = 1,interval = 1000,autoUnsubscribe = true],keepBinary = false,routineId = b40ada9f- 552D-41eb-90b5-3384526eb7b9]
答案 0 :(得分:1)
从FilterFactory返回一个匿名类的实例,该实例又引用了不可序列化的封闭FilterFactory。 只需将返回的匿名CacheEntryEventFilter类替换为相应的嵌套静态类。
答案 1 :(得分:0)
您需要在拓扑中的所有节点上明确部署CQ类(特定于远程过滤器)。只需用它们创建一个JAR文件,然后在启动节点之前将其放入result["outputs"].float_val
文件夹。