I’m trying to understand what is the proper way of working with StreamReceiver
‘s which are used with IgniteDataStreamer
where keepBinary(true)
is set. Consider this code:
IgniteDataStreamer<MyPojoKey, MyPojoEntity> streamer = ignite.dataStreamer(cacheName);
streamer.keepBinary(true);
streamer.receiver(new MyReceiver());
Now, the thing is – MyReceiver
must implement StreamReceiver<MyPojoKey, MyPojoEntity>
, but not StreamReceiver<BinaryObject, BinaryObject>
– otherwise the code above won’t compile. As the result, the receive
method looks like that:
public class MyReceiver implements StreamReceiver<MyPojoKey, MyPojoEntity> {
@Override
void receive(IgniteCache<MyPojoKey, MyPojoEntity> cache,
Collection<Map.Entry<MyPojoKey, MyPojoEntity>> entries) {
//
}
}
Now, the key and the value that come in the entries
collection are not MyPojoKey
and MyPojoEntity
! Since keepBinary
was called above with true
, they’re BinaryObjectImpl
‘s – where BinaryObjectImpl
is an Ignite type – which is possible only due to Java’s type erasure. I can cast them to proper BinaryObject
of course and then work with them as such:
void receive(IgniteCache<MyPojoKey, MyPojoEntity> cache,
Collection<Map.Entry<MyPojoKey, MyPojoEntity>> entries) {
entries.forEach(entry -> {
// Notice I can't do "MyPojoEntity en = entry.getValue()" - that would throw ClassCastException
BinaryObject binaryEntity = (BinaryObject)entry.getValue();
// Notice unchecked cast to raw IgniteCache - can't compile it otherwise!
((IgniteCache)cache).put(key, binaryEntity);
});
}
The code above works as expected, although with those very dirty tricks with type erasure, to work around what effectively is java heap pollution. So it’s quite a bit twisted, isn’t it?
Sure thing, a simpler and safer workaround is probably making MyReceiver
implement StreamReceiver<BinaryObject, BinaryObject>
, and then use the raw type of IgniteDataStreamer
:
// ...
((IgniteDataStreamer)streamer).receiver(new MyReceiver()); // Cast to raw IgniteDataStreamer
// ... and where MyReceiver now implements StreamReceiver<BinaryObject, BinaryObject>
, in which case at least MyReceiver can be implemented as properly strongly typed. But still it looks like a dirty hack, so I suspect it’s me doing something wrong there?