[JBoss JIRA] (ISPN-3271) Connection leaks in JdbcBinaryCacheStore
by Nicolas Filotto (JIRA)
[ https://issues.jboss.org/browse/ISPN-3271?page=com.atlassian.jira.plugin.... ]
Nicolas Filotto updated ISPN-3271:
----------------------------------
Affects Version/s: (was: 5.2.6.Final)
(was: 5.3.0.CR2)
> Connection leaks in JdbcBinaryCacheStore
> ----------------------------------------
>
> Key: ISPN-3271
> URL: https://issues.jboss.org/browse/ISPN-3271
> Project: Infinispan
> Issue Type: Bug
> Components: Loaders and Stores
> Affects Versions: 5.1.7.Final
> Reporter: Nicolas Filotto
> Assignee: Mircea Markus
>
> It seems that there is a connection leak in the method {{purgeInternal}} of the class {{JdbcBinaryCacheStore}}. Indeed in this method, there are situations where {{connectionFactory.releaseConnection(conn)}} is not called for example in case {{emptyBuckets.isEmpty()}} or {{expiredBuckets.isEmpty()}}.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira
11 years, 2 months
[JBoss JIRA] (ISPN-3032) Use both context and class' class loader when reading component metadata
by Galder Zamarreño (JIRA)
[ https://issues.jboss.org/browse/ISPN-3032?page=com.atlassian.jira.plugin.... ]
Galder Zamarreño updated ISPN-3032:
-----------------------------------
Fix Version/s: 6.0.0.Final
Affects Version/s: 5.3.0.Final
> Use both context and class' class loader when reading component metadata
> ------------------------------------------------------------------------
>
> Key: ISPN-3032
> URL: https://issues.jboss.org/browse/ISPN-3032
> Project: Infinispan
> Issue Type: Bug
> Affects Versions: 5.3.0.Final
> Reporter: Mircea Markus
> Assignee: Tristan Tarrant
> Fix For: 6.0.0.CR2, 6.0.0.Final
>
>
> {quote}
> Caused by: org.hibernate.search.SearchException: Unable to initialize
> directory provider:
> org.hibernate.search.test.integration.jbossas7.model.Member
> at org.hibernate.search.store.impl.DirectoryProviderFactory.createDirectoryProvider(DirectoryProviderFactory.java:87)
> at org.hibernate.search.indexes.impl.DirectoryBasedIndexManager.createDirectoryProvider(DirectoryBasedIndexManager.java:232)
> at org.hibernate.search.indexes.impl.DirectoryBasedIndexManager.initialize(DirectoryBasedIndexManager.java:100)
> at org.hibernate.search.indexes.impl.IndexManagerHolder.createIndexManager(IndexManagerHolder.java:227)
> ... 19 more
> Caused by: org.infinispan.config.ConfigurationException:
> org.infinispan.CacheException: Unable to load component metadata!
> at org.infinispan.manager.DefaultCacheManager.<init>(DefaultCacheManager.java:386)
> at org.infinispan.manager.DefaultCacheManager.<init>(DefaultCacheManager.java:341)
> at org.infinispan.manager.DefaultCacheManager.<init>(DefaultCacheManager.java:328)
> at org.hibernate.search.infinispan.CacheManagerServiceProvider.start(CacheManagerServiceProvider.java:93)
> at org.hibernate.search.engine.impl.StandardServiceManager$ServiceProviderWrapper.startVirtual(StandardServiceManager.java:178)
> at org.hibernate.search.engine.impl.StandardServiceManager.requestService(StandardServiceManager.java:124)
> at org.hibernate.search.infinispan.impl.InfinispanDirectoryProvider.initialize(InfinispanDirectoryProvider.java:86)
> at org.hibernate.search.store.impl.DirectoryProviderFactory.createDirectoryProvider(DirectoryProviderFactory.java:84)
> ... 22 more
> Caused by: org.infinispan.CacheException: Unable to load component metadata!
> at org.infinispan.factories.components.ComponentMetadataRepo.initialize(ComponentMetadataRepo.java:131)
> at org.infinispan.factories.GlobalComponentRegistry.<init>(GlobalComponentRegistry.java:103)
> at org.infinispan.manager.DefaultCacheManager.<init>(DefaultCacheManager.java:381)
> ... 29 more
> Caused by: java.lang.NullPointerException
> at org.infinispan.factories.components.ComponentMetadataRepo.readMetadata(ComponentMetadataRepo.java:53)
> at org.infinispan.factories.components.ComponentMetadataRepo.initialize(ComponentMetadataRepo.java:129)
> ... 31 more
> {quote}
> The exception above is caused by Infinispan using (by default) invocation context's ClassLoader when trying to read the component metadata. In a modularized environment such as AS7 this will cause the metadata not to be found (metadata is packaged in the same jar as the infinispan class that reads it). In order to overcome this problem we should try to use both class' ClassLoader and InvocationContxt's class loader when trying to read the metadata.
> Workaround: set the class loader on the GlobalConfiguration object:
> {code:java}
> GlobalConfiguration.classLoader( GlobalConfiguration.class.getClassLoder())
> {code}
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira
11 years, 2 months
[JBoss JIRA] (ISPN-3032) Use both context and class' class loader when reading component metadata
by Galder Zamarreño (JIRA)
[ https://issues.jboss.org/browse/ISPN-3032?page=com.atlassian.jira.plugin.... ]
Galder Zamarreño updated ISPN-3032:
-----------------------------------
Status: Resolved (was: Pull Request Sent)
Resolution: Done
> Use both context and class' class loader when reading component metadata
> ------------------------------------------------------------------------
>
> Key: ISPN-3032
> URL: https://issues.jboss.org/browse/ISPN-3032
> Project: Infinispan
> Issue Type: Bug
> Affects Versions: 5.3.0.Final
> Reporter: Mircea Markus
> Assignee: Tristan Tarrant
> Fix For: 6.0.0.CR2, 6.0.0.Final
>
>
> {quote}
> Caused by: org.hibernate.search.SearchException: Unable to initialize
> directory provider:
> org.hibernate.search.test.integration.jbossas7.model.Member
> at org.hibernate.search.store.impl.DirectoryProviderFactory.createDirectoryProvider(DirectoryProviderFactory.java:87)
> at org.hibernate.search.indexes.impl.DirectoryBasedIndexManager.createDirectoryProvider(DirectoryBasedIndexManager.java:232)
> at org.hibernate.search.indexes.impl.DirectoryBasedIndexManager.initialize(DirectoryBasedIndexManager.java:100)
> at org.hibernate.search.indexes.impl.IndexManagerHolder.createIndexManager(IndexManagerHolder.java:227)
> ... 19 more
> Caused by: org.infinispan.config.ConfigurationException:
> org.infinispan.CacheException: Unable to load component metadata!
> at org.infinispan.manager.DefaultCacheManager.<init>(DefaultCacheManager.java:386)
> at org.infinispan.manager.DefaultCacheManager.<init>(DefaultCacheManager.java:341)
> at org.infinispan.manager.DefaultCacheManager.<init>(DefaultCacheManager.java:328)
> at org.hibernate.search.infinispan.CacheManagerServiceProvider.start(CacheManagerServiceProvider.java:93)
> at org.hibernate.search.engine.impl.StandardServiceManager$ServiceProviderWrapper.startVirtual(StandardServiceManager.java:178)
> at org.hibernate.search.engine.impl.StandardServiceManager.requestService(StandardServiceManager.java:124)
> at org.hibernate.search.infinispan.impl.InfinispanDirectoryProvider.initialize(InfinispanDirectoryProvider.java:86)
> at org.hibernate.search.store.impl.DirectoryProviderFactory.createDirectoryProvider(DirectoryProviderFactory.java:84)
> ... 22 more
> Caused by: org.infinispan.CacheException: Unable to load component metadata!
> at org.infinispan.factories.components.ComponentMetadataRepo.initialize(ComponentMetadataRepo.java:131)
> at org.infinispan.factories.GlobalComponentRegistry.<init>(GlobalComponentRegistry.java:103)
> at org.infinispan.manager.DefaultCacheManager.<init>(DefaultCacheManager.java:381)
> ... 29 more
> Caused by: java.lang.NullPointerException
> at org.infinispan.factories.components.ComponentMetadataRepo.readMetadata(ComponentMetadataRepo.java:53)
> at org.infinispan.factories.components.ComponentMetadataRepo.initialize(ComponentMetadataRepo.java:129)
> ... 31 more
> {quote}
> The exception above is caused by Infinispan using (by default) invocation context's ClassLoader when trying to read the component metadata. In a modularized environment such as AS7 this will cause the metadata not to be found (metadata is packaged in the same jar as the infinispan class that reads it). In order to overcome this problem we should try to use both class' ClassLoader and InvocationContxt's class loader when trying to read the metadata.
> Workaround: set the class loader on the GlobalConfiguration object:
> {code:java}
> GlobalConfiguration.classLoader( GlobalConfiguration.class.getClassLoder())
> {code}
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira
11 years, 2 months
[JBoss JIRA] (ISPN-3295) Add a warning message to the log if the old bundler is enabled
by Bela Ban (JIRA)
[ https://issues.jboss.org/browse/ISPN-3295?page=com.atlassian.jira.plugin.... ]
Bela Ban commented on ISPN-3295:
--------------------------------
#1 You could use Protocol.getValue(). Yes - this uses reflection
#2 The old bundler should not be used anymore - I'll deprecate it at some point. Why would Infinispan want to use the old bundler ?
> Add a warning message to the log if the old bundler is enabled
> --------------------------------------------------------------
>
> Key: ISPN-3295
> URL: https://issues.jboss.org/browse/ISPN-3295
> Project: Infinispan
> Issue Type: Bug
> Affects Versions: 5.3.0.Final
> Reporter: Alan Field
> Assignee: Pedro Ruivo
> Fix For: 6.0.0.Final
>
>
> In JGroups 3.3, the new bundler is the default. If the old bundler is enabled (i.e. UDP.bundler_type="old") then Infinispan performance is adversely affected. Infinispan should warn if the old bundler is enabled to notify users of this situation.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira
11 years, 2 months
[JBoss JIRA] (ISPN-3665) SingleFileStore is not thread-safe for passivation
by Paul Ferraro (JIRA)
[ https://issues.jboss.org/browse/ISPN-3665?page=com.atlassian.jira.plugin.... ]
Paul Ferraro updated ISPN-3665:
-------------------------------
Status: Pull Request Sent (was: Open)
Git Pull Request: https://github.com/infinispan/infinispan/pull/2180
> SingleFileStore is not thread-safe for passivation
> --------------------------------------------------
>
> Key: ISPN-3665
> URL: https://issues.jboss.org/browse/ISPN-3665
> Project: Infinispan
> Issue Type: Bug
> Components: Loaders and Stores
> Affects Versions: 6.0.0.CR1
> Reporter: Paul Ferraro
> Assignee: Mircea Markus
> Priority: Blocker
> Fix For: 6.0.0.Final
>
> Attachments: Test.java
>
>
> SingleFileStore never makes use of FileChannel.force(...) to flush changes to disk. This causes problems for the passivation use case.
> If one thread evicts a cache entry, while immediately after another thread attempts to read the same cache entry, the Cache.get(...) can return null. This is because the entry is never flushed to disk.
> I've attached a test to reproduce the problem.
> I also ran the same test with the addition of FileChannel.force(false) to the write(...) method, and the test succeeds.
> A proper fix should probably make this a configurable property (as it was with the old file store implementation). It would be nice if the flush could defer until just before tx commit, but, off hand, I don't know how feasible that is.
> I suspect this lack of flush also accounts for much of the bold claim of a 100x performance improvement over the old file store implementation.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira
11 years, 2 months
[JBoss JIRA] (ISPN-3665) SingleFileStore is not thread-safe for passivation
by Paul Ferraro (JIRA)
[ https://issues.jboss.org/browse/ISPN-3665?page=com.atlassian.jira.plugin.... ]
Paul Ferraro reassigned ISPN-3665:
----------------------------------
Assignee: Paul Ferraro (was: Mircea Markus)
> SingleFileStore is not thread-safe for passivation
> --------------------------------------------------
>
> Key: ISPN-3665
> URL: https://issues.jboss.org/browse/ISPN-3665
> Project: Infinispan
> Issue Type: Bug
> Components: Loaders and Stores
> Affects Versions: 6.0.0.CR1
> Reporter: Paul Ferraro
> Assignee: Paul Ferraro
> Priority: Blocker
> Fix For: 6.0.0.Final
>
> Attachments: Test.java
>
>
> SingleFileStore never makes use of FileChannel.force(...) to flush changes to disk. This causes problems for the passivation use case.
> If one thread evicts a cache entry, while immediately after another thread attempts to read the same cache entry, the Cache.get(...) can return null. This is because the entry is never flushed to disk.
> I've attached a test to reproduce the problem.
> I also ran the same test with the addition of FileChannel.force(false) to the write(...) method, and the test succeeds.
> A proper fix should probably make this a configurable property (as it was with the old file store implementation). It would be nice if the flush could defer until just before tx commit, but, off hand, I don't know how feasible that is.
> I suspect this lack of flush also accounts for much of the bold claim of a 100x performance improvement over the old file store implementation.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira
11 years, 2 months
[JBoss JIRA] (ISPN-3665) SingleFileStore is not thread-safe for passivation
by Paul Ferraro (JIRA)
[ https://issues.jboss.org/browse/ISPN-3665?page=com.atlassian.jira.plugin.... ]
Paul Ferraro commented on ISPN-3665:
------------------------------------
I have not. We are trying to keep Wildfly free of native code.
> SingleFileStore is not thread-safe for passivation
> --------------------------------------------------
>
> Key: ISPN-3665
> URL: https://issues.jboss.org/browse/ISPN-3665
> Project: Infinispan
> Issue Type: Bug
> Components: Loaders and Stores
> Affects Versions: 6.0.0.CR1
> Reporter: Paul Ferraro
> Assignee: Mircea Markus
> Priority: Blocker
> Fix For: 6.0.0.Final
>
> Attachments: Test.java
>
>
> SingleFileStore never makes use of FileChannel.force(...) to flush changes to disk. This causes problems for the passivation use case.
> If one thread evicts a cache entry, while immediately after another thread attempts to read the same cache entry, the Cache.get(...) can return null. This is because the entry is never flushed to disk.
> I've attached a test to reproduce the problem.
> I also ran the same test with the addition of FileChannel.force(false) to the write(...) method, and the test succeeds.
> A proper fix should probably make this a configurable property (as it was with the old file store implementation). It would be nice if the flush could defer until just before tx commit, but, off hand, I don't know how feasible that is.
> I suspect this lack of flush also accounts for much of the bold claim of a 100x performance improvement over the old file store implementation.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira
11 years, 2 months
[JBoss JIRA] (ISPN-3665) SingleFileStore is not thread-safe for passivation
by Paul Ferraro (JIRA)
[ https://issues.jboss.org/browse/ISPN-3665?page=com.atlassian.jira.plugin.... ]
Paul Ferraro updated ISPN-3665:
-------------------------------
Description:
SingleFileStore never makes use of FileChannel.force(...) to flush changes to disk. This causes problems for the passivation use case.
If one thread evicts a cache entry, while immediately after another thread attempts to read the same cache entry, the Cache.get(...) can return null. This is because the entry is never flushed to disk.
I've attached a test to reproduce the problem.
I also ran the same test with the addition of FileChannel.force(false) to the write(...) method, and the test succeeds.
A proper fix should probably make this a configurable property (as it was with the old file store implementation). It would be nice if the flush could defer until just before tx commit, but, off hand, I don't know how feasible that is.
I suspect this lack of flush also accounts for much of the bold claim of a 100x performance improvement over the old file store implementation.
was:
SingleFileStore never makes use of FileChannel.force(...) to flush changes to disk. This causes problems for the passivation use case.
If one thread evicts a cache entry, while immediately after another thread attempts to read the same cache entry, the Cache.get(...) can return null. This is because the entry is never flushed to disk.
I've attached a test to reproduce the problem.
I also ran the same test with the addition of FileChannel.force(false) to the write(...) method, and the test succeeds.
A proper fix should probably make this a configurable property (as it was with the old file store implementation). It would be nice if the flush could defer until just before tx commit.
I suspect this lack of flush also accounts for much of the bold claim of a 100x performance improvement over the old file store implementation.
> SingleFileStore is not thread-safe for passivation
> --------------------------------------------------
>
> Key: ISPN-3665
> URL: https://issues.jboss.org/browse/ISPN-3665
> Project: Infinispan
> Issue Type: Bug
> Components: Loaders and Stores
> Affects Versions: 6.0.0.CR1
> Reporter: Paul Ferraro
> Assignee: Mircea Markus
> Priority: Blocker
> Fix For: 6.0.0.Final
>
> Attachments: Test.java
>
>
> SingleFileStore never makes use of FileChannel.force(...) to flush changes to disk. This causes problems for the passivation use case.
> If one thread evicts a cache entry, while immediately after another thread attempts to read the same cache entry, the Cache.get(...) can return null. This is because the entry is never flushed to disk.
> I've attached a test to reproduce the problem.
> I also ran the same test with the addition of FileChannel.force(false) to the write(...) method, and the test succeeds.
> A proper fix should probably make this a configurable property (as it was with the old file store implementation). It would be nice if the flush could defer until just before tx commit, but, off hand, I don't know how feasible that is.
> I suspect this lack of flush also accounts for much of the bold claim of a 100x performance improvement over the old file store implementation.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira
11 years, 2 months
[JBoss JIRA] (ISPN-3665) SingleFileStore is not thread-safe for passivation
by Paul Ferraro (JIRA)
Paul Ferraro created ISPN-3665:
----------------------------------
Summary: SingleFileStore is not thread-safe for passivation
Key: ISPN-3665
URL: https://issues.jboss.org/browse/ISPN-3665
Project: Infinispan
Issue Type: Bug
Components: Loaders and Stores
Affects Versions: 6.0.0.CR1
Reporter: Paul Ferraro
Assignee: Mircea Markus
Priority: Blocker
Fix For: 6.0.0.Final
Attachments: Test.java
SingleFileStore never makes use of FileChannel.force(...) to flush changes to disk. This causes problems for the passivation use case.
If one thread evicts a cache entry, while immediately after another thread attempts to read the same cache entry, the Cache.get(...) can return null. This is because the entry is never flushed to disk.
I've attached a test to reproduce the problem.
I also ran the same test with the addition of FileChannel.force(false) to the write(...) method, and the test succeeds.
A proper fix should probably make this a configurable operation (as it was with the old file store implementation). It would be nice if the flush could defer until just before tx commit.
I suspect this lack of flush also accounts for much of the bold claim of a 100x performance improvement over the old file store implementation.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira
11 years, 2 months
[JBoss JIRA] (ISPN-3664) Improve write command processing
by Pedro Ruivo (JIRA)
[ https://issues.jboss.org/browse/ISPN-3664?page=com.atlassian.jira.plugin.... ]
Pedro Ruivo updated ISPN-3664:
------------------------------
Description:
Major refactorization of the write command with the following goals:
-> Base WriteCommand: all the write command has the same workflow through the interceptor chain
-> Create a concrete WriteCommand for each operation (put, remove, replace, replaceIfEquals, removeIfEquals, putIfAbsent)
-> Extend the interceptor chain to process each one of the command and add a new "visitWriteCommand", that is invoked by the default visitX methods.
-> (minor) change the GetKeyValueCommand to ReadCommand to make name "compatible" with WriteCommand.
Note that most of the interceptor only needs to implement the visitWriteCommand because all the write command has the same execution flow. The basic flow of the write commands are: (non-tx) lock, fetch value (cachestore/remote), check condition and apply change. for tx mode, lock (if pessimistic), fetch value (cache loader, remote, etc), apply change and add it to the transaction (if successful)
Also, another advantage is the simplification of the EntryFactory because if we think a little about it, independent of the write command we need to wrap the entry anyway.
Suggested implementation
{code:java}
class abstract WriteCommand
Object key, Object newValue
boolen match(Object currentValue) //true by default
boolean needsRemoteGetBeforeWrite() //true by default
object perform() //common implementation like: if (match(entry.getValue()) then entry.setValue(newValue); entry.setChanged(true); entry.setRemoved(newValue == null)}
{code}
* Concrete implementations*
{code:java}
{PutCommand|RemoveCommand} extends WriteCommand
ovewrite needsRemoteGetBeforeWrite() {return !flags.contains(IGNORE_RETURN_VALUE)}
ReplaceIfPresentCommand extends WriteCommand
ovewrite match(Object currentValue) {return currentValue != null}
PutIfAbsentCommand extends WriteCommand
ovewrite match(Object currentValue) {return currentValue == null}
{code}
* Special base class for operation with expected value to compare*
{code:java}
class abstract AdvancedWriteCommand extends WriteCommand
Object expectedValue
match(Object currentValue) {return currentValue.equals(expectedValue)}
{RemoveIfEquals|ReplaceIfEquals} extends AdvancedWriteCommand //no different implementation needed.
{code}
ps: I'm going to open the discussion in the dev mailing list...
was:
Major refactorization of the write command with the following goals:
-> Base WriteCommand: all the write command has the same workflow through the interceptor chain
-> Create a concrete WriteCommand for each operation (put, remove, replace, replaceIfEquals, removeIfEquals, putIfAbsent)
-> Extend the interceptor chain to process each one of the command and add a new "visitWriteCommand", that is invoked by the default visitX methods.
-> (minor) change the GetKeyValueCommand to ReadCommand to make name "compatible" with WriteCommand.
The above it is safe and it would make the code simple. The basic flow of the write commands are: (non-tx) lock, fetch value (cachestore/remote), check condition and apply change
Suggested implementation
{code:java}
class abstract WriteCommand
Object key, Object newValue
boolen match(Object currentValue) //true by default
boolean needsRemoteGetBeforeWrite() //true by default
object perform() //common implementation like: if (match(entry.getValue()) then entry.setValue(newValue); entry.setChanged(true); entry.setRemoved(newValue == null)}
{code}
* Concrete implementations*
{code:java}
{PutCommand|RemoveCommand} extends WriteCommand
ovewrite needsRemoteGetBeforeWrite() {return !flags.contains(IGNORE_RETURN_VALUE)}
ReplaceIfPresentCommand extends WriteCommand
ovewrite match(Object currentValue) {return currentValue != null}
PutIfAbsentCommand extends WriteCommand
ovewrite match(Object currentValue) {return currentValue == null}
{code}
* Special base class for operation with expected value to compare*
{code:java}
class abstract AdvancedWriteCommand extends WriteCommand
Object expectedValue
match(Object currentValue) {return currentValue.equals(expectedValue)}
{RemoveIfEquals|ReplaceIfEquals} extends AdvancedWriteCommand //no different implementation needed.
{code}
ps: I'm going to open the discussion in the dev mailing list...
> Improve write command processing
> --------------------------------
>
> Key: ISPN-3664
> URL: https://issues.jboss.org/browse/ISPN-3664
> Project: Infinispan
> Issue Type: Enhancement
> Affects Versions: 6.0.0.CR1
> Reporter: Pedro Ruivo
> Assignee: Pedro Ruivo
> Fix For: 7.0.0.Final
>
>
> Major refactorization of the write command with the following goals:
> -> Base WriteCommand: all the write command has the same workflow through the interceptor chain
> -> Create a concrete WriteCommand for each operation (put, remove, replace, replaceIfEquals, removeIfEquals, putIfAbsent)
> -> Extend the interceptor chain to process each one of the command and add a new "visitWriteCommand", that is invoked by the default visitX methods.
> -> (minor) change the GetKeyValueCommand to ReadCommand to make name "compatible" with WriteCommand.
> Note that most of the interceptor only needs to implement the visitWriteCommand because all the write command has the same execution flow. The basic flow of the write commands are: (non-tx) lock, fetch value (cachestore/remote), check condition and apply change. for tx mode, lock (if pessimistic), fetch value (cache loader, remote, etc), apply change and add it to the transaction (if successful)
> Also, another advantage is the simplification of the EntryFactory because if we think a little about it, independent of the write command we need to wrap the entry anyway.
> Suggested implementation
> {code:java}
> class abstract WriteCommand
> Object key, Object newValue
> boolen match(Object currentValue) //true by default
> boolean needsRemoteGetBeforeWrite() //true by default
> object perform() //common implementation like: if (match(entry.getValue()) then entry.setValue(newValue); entry.setChanged(true); entry.setRemoved(newValue == null)}
> {code}
> * Concrete implementations*
> {code:java}
> {PutCommand|RemoveCommand} extends WriteCommand
> ovewrite needsRemoteGetBeforeWrite() {return !flags.contains(IGNORE_RETURN_VALUE)}
> ReplaceIfPresentCommand extends WriteCommand
> ovewrite match(Object currentValue) {return currentValue != null}
> PutIfAbsentCommand extends WriteCommand
> ovewrite match(Object currentValue) {return currentValue == null}
> {code}
> * Special base class for operation with expected value to compare*
> {code:java}
> class abstract AdvancedWriteCommand extends WriteCommand
> Object expectedValue
> match(Object currentValue) {return currentValue.equals(expectedValue)}
> {RemoveIfEquals|ReplaceIfEquals} extends AdvancedWriteCommand //no different implementation needed.
> {code}
> ps: I'm going to open the discussion in the dev mailing list...
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira
11 years, 2 months