MapLoader initialization

810 views
Skip to first unread message

Ges

unread,
Aug 29, 2010, 12:27:29 AM8/29/10
to Hazelcast
Hi,

I'm trying to figure out a way to initialize a MapLoader instance for
a given map. I can define the class in the configuration but how do I
pass some initialization data to the instance created by Hazelcast? I
did see some discussion already on this, but I did not come across any
concrete approach.

Thanks,
Gesly

Talip Ozturk

unread,
Aug 29, 2010, 1:54:59 AM8/29/10
to haze...@googlegroups.com
1. [Optional] If needed, set custom properties for your
MapLoader/Store then in your hazelcast xml configuration. Here is an
example:

<hazelcast>
...
<map name="default">
...
<map-store enabled="true">
<class-name>...</class-name>
<myproperty1>value1</myproperty1>
<myproperty2>value2</myproperty2>
...

2. Make sure your MapLoader implementation extends
com.hazelcast.core.AbstractMapStore implements MapLoader and override
AbstractMapStore.init(HazelcastInstance hazelcastInstance,
Properties properties, String mapName)
// Do all your initialization here.

witter @oztalip

> --
> You received this message because you are subscribed to the Google Groups "Hazelcast" group.
> To post to this group, send email to haze...@googlegroups.com.
> To unsubscribe from this group, send email to hazelcast+...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/hazelcast?hl=en.
>
>

Ges

unread,
Aug 29, 2010, 2:31:09 AM8/29/10
to Hazelcast
Talip, Thanks for the quick response. I'll give this a try.

Another question, when kind of a lookup calls loadAll(Collection
keys)?

Talip Ozturk

unread,
Aug 29, 2010, 2:57:23 AM8/29/10
to haze...@googlegroups.com
> Another question, when kind of a lookup calls loadAll(Collection
> keys)?

It is never called yet. We will have map.getAll(keys) which will use
loadAll(keys).

It is also part of the JCache spec.

https://jsr-107-interest.dev.java.net/javadoc/javax/cache/CacheLoader.html

twitter @oztalip

Ges

unread,
Sep 1, 2010, 1:30:49 PM9/1/10
to Hazelcast
Btw, I am using the latest 1.9 snapshot available for download.
> https://jsr-107-interest.dev.java.net/javadoc/javax/cache/CacheLoader...
>
> twitter @oztalip

Ges

unread,
Sep 1, 2010, 1:30:07 PM9/1/10
to Hazelcast
Talip,

What happens when the loader does not find a value and hence returns
null?

I see the following behavior:

I have a 3 node setup with the default setting of 1 backup node and
MapLoader defined.

1. I request an item that does not exist in the map; the loader gets
called but the loader returns null as it cannot find a value for the
key. So I get a null value which is as I expect. If I retry for the
same key, I get the same behavior as expected i.e. the key is not in
the map and it calls the loader and the loader returns null.

2. Now I take down the node and bring it back up. When I request the
same key again, I get a NullPointerException and I believe this
happens when this node is the owner of the key. I say so because at
times when I request the key, the loader is executed on a different
node and everything works as expected.

I will try few more tests but if you have any tips that would be
useful.

Thanks
> https://jsr-107-interest.dev.java.net/javadoc/javax/cache/CacheLoader...
>
> twitter @oztalip

Talip Ozturk

unread,
Sep 1, 2010, 4:54:43 PM9/1/10
to haze...@googlegroups.com
Ges,

Please post the full stacktrace for the NullPointerException.

twitter @oztalip

Ges

unread,
Sep 1, 2010, 6:21:56 PM9/1/10
to Hazelcast
Exception in thread "hz.executor._hzInstance_0_dev.cached.thread-34"
java.lang.RuntimeException: CONCURRENT_MAP_GET failed at
Address[X.X.X.X:5702
] because of an exception thrown at Address[X.X.X.X:5701]
at
com.hazelcast.impl.BaseManager.rethrowException(BaseManager.java:114)
at com.hazelcast.impl.ConcurrentMapManager
$MGet.get(ConcurrentMapManager.java:483)
at com.hazelcast.impl.FactoryImpl$MProxyImpl
$MProxyReal.get(FactoryImpl.java:2369)
at com.hazelcast.impl.FactoryImpl
$MProxyImpl.get(FactoryImpl.java:1935)
at com.hazelcast.impl.FactoryImpl$MProxyImpl
$1.call(FactoryImpl.java:1959)
at com.hazelcast.impl.AsyncCall.run(AsyncCall.java:34)
at com.hazelcast.impl.executor.ParallelExecutorService
$ParallelExecutorImpl
$ExecutionSegment.run(ParallelExecutorService.java:136)
at java.util.concurrent.ThreadPoolExecutor
$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.NullPointerException
at
com.aqr.pricingsvc.store.PriceStoreLoader.load(PriceStoreLoader.java:
43)
at
com.aqr.pricingsvc.store.PriceStoreLoader.load(PriceStoreLoader.java:
15)
at
com.hazelcast.impl.concurrentmap.MapStoreWrapper.load(MapStoreWrapper.java:
101)
at com.hazelcast.impl.ConcurrentMapManager
$StoreAwareOperationHandler.execute(ConcurrentMapManager.java:1749)
at com.hazelcast.impl.ConcurrentMapManager
$OrderedExecutionTask.run(ConcurrentMapManager.java:2042)
at com.hazelcast.impl.executor.ParallelExecutorService
$ParallelExecutorImpl
$ExecutionSegment.run(ParallelExecutorService.java:135)
at java.util.concurrent.ThreadPoolExecutor
$Worker.runTask(ThreadPoolExecutor.java:886)
... 2 more

Talip Ozturk

unread,
Sep 1, 2010, 6:45:35 PM9/1/10
to haze...@googlegroups.com
Ges,

StackTrace tells me that
1. Hazelcast called your PriceStoreLoader on get
2. PriceStoreLoader failed with NPE
3. Hazelcast propagated the NPE back to the caller

These are all looking fine from Hazelcast side. Can you tell us what
might be -Null- at PriceStoreLoader (line 43)? Please post this line
if possible.

-talip

Ges

unread,
Sep 1, 2010, 9:24:21 PM9/1/10
to Hazelcast
I have been investigating line 43 all along but I was not seeing
anything in my logs or in the debugger on that line. But I just
realized that I was not reading the stack trace correctly - the actual
exception was taking place on a different node.

The NPE is being thrown because of loader initialization issues.

I initialize my loader in the following way:

MapConfig mapConfig = Hazelcast.getConfig().getMapConfig("store");
MapStoreConfig mapStoreConfig = mapConfig.getMapStoreConfig();
PriceStoreLoader loader = (PriceStoreLoader)
mapStoreConfig.getImplementation();
if (loader == null) {
loader = new PriceStoreLoader();
mapStoreConfig.setImplementation(loader);
}
loader.init(idcPriceSource, (HazelCastPriceStore) store);

If init() is not called on the 'loader', then its initialization is
incomplete. But it looks like, a loader object (say loader1) is
created when the map is obtained and then the above code creates
another loader object (loader2) and initializes it. Hazelcast is
calling the load on loader1 and not loader2. I used the above code to
initialize the loader, so that I could initialize it with the
necessary dependencies.

Mistake is mine. I should have looked at the trace more carefully.
Could you shed some light on what might be happening?

Thanks

Ges

unread,
Sep 3, 2010, 12:03:08 PM9/3/10
to Hazelcast
Talip,

I made a few changes (I no longer use the initialization approach
mentioned above) and now I have it working correctly (well almost),
but I see something strange. I had extended AbstractMapStore in my
PriceStoreLoader (in addition to implementing MapLoader) but did not
implement any of the store() methods (all the methods were empty
stubs) as I only wanted Loader functionality.

When the loader's load method get called due to a missing key, I
obtain a set of data and bulk load into the Hazelcast map in addition
to returning the expected value. This put() operation on the map
always stalls after 16 items are added (I have tried with different
data sets). Below is the stack dump of the Hazelcast thread.

Thread [hz.executor._hzInstance_0_dev.cached.thread-2] (Suspended)
Object.wait(long) line: not available [native method]
SimpleBlockingQueue<E>.poll(long, TimeUnit) line: 97
ConcurrentMapManager$MPut(BaseManager
$ResponseQueueCall).waitAndGetResult() line: 431
ConcurrentMapManager$MPut(BaseManager
$ResponseQueueCall).getRedoAwareResult() line: 456
ConcurrentMapManager$MPut(BaseManager$ResponseQueueCall).getResult()
line: 452
ConcurrentMapManager$MPut(BaseManager
$RequestBasedCall).getResultAsObject() line: 334
ConcurrentMapManager$MPut.txnalPut(ClusterOperation, String, Object,
Object, long, long) line: 894
ConcurrentMapManager$MPut.put(String, Object, Object, long, long)
line: 782
FactoryImpl$MProxyImpl$MProxyReal.put(Object, Object, long, long)
line: 2324
FactoryImpl$MProxyImpl$MProxyReal.put(Object, Object, long, TimeUnit)
line: 2316
FactoryImpl$MProxyImpl.put(Object, Object, long, TimeUnit) line:
1983
FactoryImpl$MProxyImpl.put(Object, Object) line: 1950
HazelCastPriceStore.add(String, Price) line: 83
HazelCastPriceStore.add(Collection<Price>) line: 107
PriceStoreLoader.load(HazelCastPriceStore$PriceKey) line: 56
<unknown receiving type>(PriceStoreLoader).load(Object) line: 1
MapStoreWrapper.load(Object) line: 101
ConcurrentMapManager$GetOperationHandler(ConcurrentMapManager
$StoreAwareOperationHandler).execute(Request) line: 1749
ConcurrentMapManager$OrderedExecutionTask.run() line: 2042
ParallelExecutorService$ParallelExecutorImpl$ExecutionSegment.run()
line: 135
ThreadPoolExecutor$Worker.runTask(Runnable) line: 886
ThreadPoolExecutor$Worker.run() line: 908
Thread.run() line: 619

I then changed my class to not extend AbstractMapStore (as I realized
this was the only change I had made) and it works just fine. I'm fine
for now as I do not need the store functionality at the moment.

Thanks,
Gesly

Talip Ozturk

unread,
Sep 12, 2010, 7:11:15 AM9/12/10
to haze...@googlegroups.com
Gesly,

1.9 final fixes this issue. Download 1.9 final (when it is available)
and change your PriceStoreLoader to

public class PriceStoreLoader implements MapLoader, MapLoaderLifecycleSupport {

// implement all required methods.
}

do not call PriceStoreLoader.init(...) yourself. Hazelcast will call
it when needed.

Also PriceStoreLoader should not call any Hazelcast IMap call like
put(), get()... because threads that are calling the MapStore/Loader
are limited. You should only do database (or datastore) operations
there. If you need to do extra IMap calls have your own threads do it
so that you don't block Hazelcast threads forever.


twitter @oztalip

Reply all
Reply to author
Forward
0 new messages