Topic
  • 13 replies
  • Latest Post - ‏2012-07-19T13:00:24Z by Erwin_Karbasi
Erwin_Karbasi
Erwin_Karbasi
186 Posts

Pinned topic Using ReduceAgent in wxsutils

‏2012-07-16T16:12:43Z |
Hello Masters,

We are using BSON DataSerializer for for serializing data into WXS.

We have tried to use the client preload from the wxsutils sample as described here in order inserting data from database into our cache.

We have failed to insert Map with one entry into the cache using "putAll_noLoader" method. If the Map is bigger than one entry we don't face with any error.

Following is our code snippet from the loader:




public Object innerReduce() 
{   System.out.println(
"PreloadAgent start reduce"); 

try 
{ WXSMap<Serializable, Serializable> remoteMap = getRemoteMap(catalogEndPoint, gridName, mapName); System.out.println(
"Connection to remote map completed! for catalogEndPoint: "+catalogEndPoint+
" grid: " + gridName+
" mapName: " + mapName);   

int partitionCount = remoteMap.getWXSUtils().getObjectGrid().getMap(mapName).getPartitionManager().getNumOfPartitions();   System.out.println(
"Number of pratitions for map: " + mapName+ 
": " + partitionCount);   

int entryCounter = 0; Map<Serializable, Serializable> batchToPut = 

new HashMap<Serializable, Serializable>(); 

if (batch.size() > (500 * partitionCount)) 
{   

for (Map.Entry<Serializable, Serializable> entry : batch.entrySet()) 
{   batchToPut.put(entry.getKey(), entry.getValue()); 

if (entryCounter++ > 500 * partitionCount) 
{ entryCounter = 0; remoteMap.putAll_noLoader(batchToPut); batchToPut = 

new HashMap<Serializable, Serializable>(); 
} 
}   
} 

else 

if (batch.size() > 0) 
{ System.out.println(
"Put All_noLoader->"+batch.size()); remoteMap.putAll_noLoader(batch); 
} System.out.println(
"PreloadAgent start reduce completed");   
} 

catch (Exception e) 
{ System.out.println(
"Exception in reduce function "+e.toString()); 

throw 

new ObjectGridRuntimeException(e); 
}   

return 

null;   
}


Following the Map that we have produced for inserting into cache:


* * Convert objects from map to BSON object */  

public Map<Serializable, Serializable> convertToBatchMap(Map<Serializable, Serializable> map) 
{ Map<Serializable, Serializable> batch = 

new HashMap<Serializable, Serializable>(); 

if (map != 

null) 
{ batch = 

new HashMap<Serializable, Serializable>();   

for (Entry<Serializable, Serializable> entry : map.entrySet()) 
{ CustomBSONObject key =json2CustomBSONObject((String) entry.getKey()); BasicDBObject value = json2CustomBSONObject((String) entry.getValue()); batch.put(key, value); 
}   
} 

return batch;   
});


Following the errors we came across:


Caused by: java.lang.IllegalArgumentException: Invalid BSONObject type: 

class java.util.HashMap at com.att.tlv.infra.services.wxs.common.bsonserializer.BSONSerializer.serializeDataObject(BSONSerializer.java:362) at com.att.tlv.infra.services.wxs.common.bsonserializer.BSONSerializer.serializeDataObject(BSONSerializer.java:347) at com.ibm.ws.objectgrid.plugins.io.dataobject.keys.KeyConversionSimple.convertPOJOToKey(KeyConversionSimple.java:136) at com.ibm.ws.objectgrid.plugins.io.dataobject.keys.KeyConversionCacheImpl.getInternalKey(KeyConversionCacheImpl.java:179) at com.ibm.ws.objectgrid.DiffMap.put(DiffMap.java:1687) at com.ibm.ws.objectgrid.DiffMap.putAll(DiffMap.java:2188) at com.ibm.ws.objectgrid.ObjectMapImpl.internalPutAll(ObjectMapImpl.java:1033) ... 8 more


If we remove following code from the class WXSReduceAgent the error disappears:




else 

if (sz == 1) 
{ 
// optimized version, generates a little less garbage. 
// invoke the agent to add the batch of records to the grid a = factory.newAgent(batch); 
// Insert all keys for one partition using the first key as a routing key AgentManager am = 

null; 

try 
{ am = utils.getSessionForThread().getMap(bmap.getName()).getAgentManager(); 
} 

catch (UndefinedMapException e) 
{ 

throw 

new ObjectGridRuntimeException(e); 
} X rc = (X) am.callReduceAgent(a, Collections.singletonList(factory.getKey(a))); Future<X> future = 

new DoneFuture<X>(rc); 

return Arrays.asList(future); 
}


Your assistance would be highly appreciated,
Erwin
Updated on 2012-07-19T13:00:24Z at 2012-07-19T13:00:24Z by Erwin_Karbasi
  • SystemAdmin
    SystemAdmin
    1485 Posts

    Re: Using ReduceAgent in wxsutils

    ‏2012-07-16T18:52:03Z  
    Is there more to that stack trace?

    What are your keys? Maps? or some simple primitive type?
  • Erwin_Karbasi
    Erwin_Karbasi
    186 Posts

    Re: Using ReduceAgent in wxsutils

    ‏2012-07-16T20:08:11Z  
    Is there more to that stack trace?

    What are your keys? Maps? or some simple primitive type?
    Hello Michael,

    Our keys are JSON format and we are storing BSON in the cache as you can see bellow:

    
    CustomBSONObject key =json2CustomBSONObject((String) entry.getKey());
    


    We are converting the JSON to CustomBSONObject because storing objects should extends from comparable.

    Thanks,
    Erwin
  • SystemAdmin
    SystemAdmin
    1485 Posts

    Re: Using ReduceAgent in wxsutils

    ‏2012-07-16T20:23:07Z  
    I think I might know the issue.

    We have an optimization when transmitting the data. We are doing an instanceof check which is probably causing an issue in your case.
    If you can test a change in the ClassSerializer.writeObject, either remove the if (f instanceof HashMap) clause or rewrite it to if (f.getClass() == HashMap.class)

    I have a feeling that your BSON object extends HashMap and is causing the problem. Am I close?
    The ClassSerializer should check for == for the specific Map/List/Set implementations to prevent breakage.
  • Erwin_Karbasi
    Erwin_Karbasi
    186 Posts

    Re: Using ReduceAgent in wxsutils

    ‏2012-07-16T21:16:08Z  
    I think I might know the issue.

    We have an optimization when transmitting the data. We are doing an instanceof check which is probably causing an issue in your case.
    If you can test a change in the ClassSerializer.writeObject, either remove the if (f instanceof HashMap) clause or rewrite it to if (f.getClass() == HashMap.class)

    I have a feeling that your BSON object extends HashMap and is causing the problem. Am I close?
    The ClassSerializer should check for == for the specific Map/List/Set implementations to prevent breakage.
    Michael,

    Thank you for quickly reply and clarification.

    In our DataSerialization we are using the BSON package of MongoDB from IBM BSON Serializer Sample.

    We didn't extend HashMap explicitly.

    We have manage to resolve this problem by removing the if clause that i provided above, but we prefer to have close wxsutils.jar file without any intervention code in order avoiding future version broking.

    Thanks,
    Erwin
  • SystemAdmin
    SystemAdmin
    1485 Posts

    Re: Using ReduceAgent in wxsutils

    ‏2012-07-18T00:46:45Z  
    Please try WXSUtils 2.7.0. This should fix the serialization issue. It also works against WXS 7.1.1 - 8.5.0.1.
  • Erwin_Karbasi
    Erwin_Karbasi
    186 Posts

    Re: Using ReduceAgent in wxsutils

    ‏2012-07-18T03:44:35Z  
    Please try WXSUtils 2.7.0. This should fix the serialization issue. It also works against WXS 7.1.1 - 8.5.0.1.
    Hello Michael,

    Thank you for quickly solution.
    We'll try it as soon as possible.

    Erwin
  • Erwin_Karbasi
    Erwin_Karbasi
    186 Posts

    Re: Using ReduceAgent in wxsutils

    ‏2012-07-18T07:29:14Z  
    Please try WXSUtils 2.7.0. This should fix the serialization issue. It also works against WXS 7.1.1 - 8.5.0.1.
    Hello Michael,

    I have one more question about wxsutils.

    We have implemented DataSerializer and we are storing BSON format into the cache.

    When we have tried to store BSONObject into the cache using putAll_noLoader method we came across error that specified that the BSONObject doesn't implement Java Comparable interface, then we convert our json format data object to our custom implimented class e.g. CustomBSONObject instead of converting them to BSONObject as follows:

    
    
    
    public Map<Serializable, Serializable> convertToBatchMap(Map<Serializable, Serializable> map) 
    { Map<Serializable, Serializable> batch = 
    
    new HashMap<Serializable, Serializable>(); 
    
    if (map != 
    
    null) 
    { batch = 
    
    new HashMap<Serializable, Serializable>();   
    
    for (Entry<Serializable, Serializable> entry : map.entrySet()) 
    {   CustomBSONObject key = converter.json2CustomBSONObject((String) entry.getKey()); BasicDBObject value = converter.json2CustomBSONObject((String) entry.getValue()); 
    
    if(key.toMap()!=
    
    null && key.toMap().size()>0 && value.toMap()!=
    
    null && value.toMap().size()>0) batch.put(key, value);   
    }   
    } 
    
    return batch;   
    }
    


    Code snippet that invoke the AgentManager method:

    
    PreloadAgent agent = 
    
    new PreloadAgent(); agentmap = convertToBatchMap(map); agent.setCatalogEndPoint( catalogEndPoint); agent.setMapName( mapName); agent.setGridName(gridName); agent.setBatch( agentmap); agent.setClientConfig( clientConfig); agent.setObjectGridClientProperties(objectGridClientProperties); 
    /** * connect to remote map */ ObjectGrid perContainerClient = WXSUtils.connectClient(catalogEndPoint, preloadAgentGridName); 
    
    if(logger.isDebugEnabled() ) logger.debug(0, 
    "-->PerContainerGrid client connected"); AgentManager am = perContainerClient.getSession().getMap(preloadAgentMapName).getAgentManager(); 
    
    if(logger.isDebugEnabled() ) logger.debug(0, 
    "-->callReduceAgent for grid  " + gridName + 
    " map " + mapName + 
    "  endpoint " + catalogEndPoint); Object rawRC = am.callReduceAgent(agent);
    


    We prefer to avoid from customizing BSONObject
    Whether the WXSUtils 2.7.0 will resolve this issue.

    Thank you a lot for assistance,
    Erwin
  • SystemAdmin
    SystemAdmin
    1485 Posts

    Re: Using ReduceAgent in wxsutils

    ‏2012-07-18T11:23:58Z  
    The Comparable is required so we can order the keys to prevent any type of deadlock across threads using putAll.
    The only way to allow plain objects is to remove this constraint which has proven to be a hidden issue with many people.

    Another way to potentially solve this would be to allow a Comparator to be used when Comparable isn't supported.
  • Erwin_Karbasi
    Erwin_Karbasi
    186 Posts

    Re: Using ReduceAgent in wxsutils

    ‏2012-07-18T13:32:28Z  
    The Comparable is required so we can order the keys to prevent any type of deadlock across threads using putAll.
    The only way to allow plain objects is to remove this constraint which has proven to be a hidden issue with many people.

    Another way to potentially solve this would be to allow a Comparator to be used when Comparable isn't supported.
    Hello Michael,

    Thanks a lot for clarification.

    Sorry, but i didn't understand your guidance here: "allow a Comparator to be used when Comparable isn't supported".

    I'd appreciate if you could clarify the best way implement your suggestion.

    Thanks,
    Erwin
  • SystemAdmin
    SystemAdmin
    1485 Posts

    Re: Using ReduceAgent in wxsutils

    ‏2012-07-18T19:14:22Z  
    Just fixed/added support for your use case.

    If you provide a SortedMap (putAll) or SortedSet (getAll) with a comparator attached, I will use the comparator instead of relying on the objects to support Comparable.
    This means that your Comparator must implement Serializable too.

    You can see the test case I added that shows an example.
  • Erwin_Karbasi
    Erwin_Karbasi
    186 Posts

    Re: Using ReduceAgent in wxsutils

    ‏2012-07-19T07:30:57Z  
    Just fixed/added support for your use case.

    If you provide a SortedMap (putAll) or SortedSet (getAll) with a comparator attached, I will use the comparator instead of relying on the objects to support Comparable.
    This means that your Comparator must implement Serializable too.

    You can see the test case I added that shows an example.
    Hello Michael,

    Thank you a lot for your quickly assistance, you helped us very much.

    I have seen in you test case that you added the following:

    
    Map<SerializedKey, String> batch = 
    
    new TreeMap<SerializedKey, String>(SerializedKey.COMPARATOR);
    


    How did you obtain "SerializedKey.COMPARATOR", i cannot find it here: com.ibm.websphere.objectgrid.plugins.io.dataobject.SerializedKey

    Thanks,
    Erwin
  • SystemAdmin
    SystemAdmin
    1485 Posts

    Re: Using ReduceAgent in wxsutils

    ‏2012-07-19T11:04:56Z  
    My bad, I forgot to commit a new class.
    Its there now.
  • Erwin_Karbasi
    Erwin_Karbasi
    186 Posts

    Re: Using ReduceAgent in wxsutils

    ‏2012-07-19T13:00:24Z  
    My bad, I forgot to commit a new class.
    Its there now.
    Thank you a lot for so quickly support.

    I'm greatly appreciating your efforts.