On Thu, May 11, 2017 at 1:54 PM, Katia Aresti <kare...@redhat.com> wrote:
> Hi Gustavo, thanks for the help ! > > Indeed, I stopped using the rv variable because I realised it was not > always the compute command result, and somehow I decided I could not take > for granted in the code that this is the compute command result value. But > I think this the case only when the PrepareCommand is called on tx mode for > this particular case. > > What confused me a lot in this matter are commands like RemoveCommand, for > example. > > private void processRemoveCommand(final RemoveCommand command, final > InvocationContext > ctx, final Object valueRemoved, TransactionContext transactionContext) > > When this method is called from the visitPrepareCommand method, we indeed > pass the previous value found just before the call in the cache. > > But after, when the same method is called from the visitRemoveCommand we > passe the rv parameter. Which is the Remove Command perfom method answer. > > > So, having a look to the RemoveCommand, I can see sometimes we indeed return > the prev value. But it might happen depending to return a boolean instead. > > > remove("key", "value")cache2.remove("newGoat"); > > *LOGS* > > Thread => 79 > ctx.getOrigin() => ClusteredCacheWithElasticsearchIndexManagerIT-NodeA-15125 > valueRemoved => Person{name='newGoat', blurb='eats something', age=42, > dateOfGraduation=null} > Thread => 38 > ctx.getOrigin() => ClusteredCacheWithElasticsearchIndexManagerIT-NodeB-23459 > valueRemoved => Person{name='newGoat', blurb='eats something', age=42, > dateOfGraduation=null} > Thread => 47 > ctx.getOrigin() => null > valueRemoved => Person{name='newGoat', blurb='eats something', age=42, > dateOfGraduation=null} > *removeFromIndexes method is called !!!* > > > But if we call remove with specific value, the method removeFromIndexes is > never called. > > cache2.remove("newGoat", person4); > > *LOGS* > > Thread => 79 > ctx.getOrigin() => ClusteredCacheWithElasticsearchIndexManagerIT-NodeA-22063 > valueRemoved => true > Thread => 38 > ctx.getOrigin() => ClusteredCacheWithElasticsearchIndexManagerIT-NodeB-47249 > valueRemoved => true > Thread => 47 > ctx.getOrigin() => null > valueRemoved => true > > But in both cases the remove seems to be working, because this assertions > work. > > found = searchManager.<Person>getQuery(allQuery, Person.class).list(); > > assertEquals(0, found.size()); > > > I'm a bit confused about all this, but we can chat o IRC or bluejeans. It > might be some bugs concerning this interceptor, Radim has already opened an > issue on this matter. > > It seems to be working, since queries results are correct, but the value is not actually removed from the indexes. https://issues.jboss.org/browse/ISPN-7825 Gustavo > Katia > > > On Wed, May 10, 2017 at 3:33 PM, Gustavo Fernandes <gust...@infinispan.org > > wrote: > >> The test fails every time NodeB (cache2) happens to *not be* the primary >> owner of 'newGoat', and needs to forward the command to NodeA. Sequence of >> events: >> >> 1) [NodeB] Compute is called, key is 'newGoat' >> 2) [NodeB] Command gets visited by the QueryInterceptor, that suspends >> the execution >> 3) [NodeB] Owner for 'newGoat' is nodeA, so nodeB forwards the command to >> nodeA >> >> 4) [NodeA] Command gets visited by the QueryInterceptor, that suspends >> the execution >> 5) [NodeA] perform() is called in the Compute command >> 6) [NodeA] Command is then sent to NodeB, which is a backup owner >> >> 7) [NodeB] Command gets visited by the QueryInterceptor, that suspends >> the execution >> 8) [NodeB] perform() is called in the compute command >> 9) [NodeB] QueryInterceptor resumes execution. Since command was >> originated remotely, no indexing is done (due to Index.LOCAL) >> >> 9) [NodeA] Receive response from the call done on 6) >> 10)[NodeA] resumes execution from the QueryInterceptor from 4) >> 11)[NodeA] Since command was originated remotely, no indexing is done >> (due to Index.LOCAL) >> >> 12)[NodeB] receives response from 3). At this point *the computed value >> is available* as the return type of the remote invocation >> 13)[NodeB] resumes the QueryInterceptor invocation from 2) >> 14)[NodeB] processComputes is then executed, but since the computedValue >> is not available in the command itself nor in the context, indexing is >> skipped since there is no value to index or remove >> >> >> Looking at the method visitComputCommand, the variable "rv" stores the >> return value from the command, but it's not being used, instead the >> stateBeforeCompute is used which is always null in this scenario, >> because it is evaluated on 2) which is before the the key exists in the >> data container: >> >> return invokeNextThenAccept(ctx, command, (rCtx, rCommand, rv) -> >> processComputeCommand(((ComputeCommand) rCommand), rCtx, stateBeforeCompute, >> null)); >> >> >> Gustavo >> >> >> On Tue, May 9, 2017 at 2:21 PM, Katia Aresti <kare...@redhat.com> wrote: >> >>> Hi all, >>> >>> I'm really struggling with something in order to finish the compute >>> methods. >>> >>> I added a test in *ClusteredCacheWithElasticsearchIndexManagerIT* >>> >>> public void testToto() throws Exception { >>> SearchManager searchManager = Search.getSearchManager(cache2); >>> QueryBuilder queryBuilder = searchManager >>> .buildQueryBuilderForClass(Person.class) >>> .get(); >>> Query allQuery = queryBuilder.all().createQuery(); >>> >>> String key = "newGoat"; >>> Person person4 = new Person(key, "eats something", 42); >>> >>> cache2.putIfAbsent(key, person4); >>> StaticTestingErrorHandler.assertAllGood(cache1, cache2); >>> >>> List<Person> found = searchManager.<Person>getQuery(allQuery, >>> Person.class).list(); >>> assertEquals(1, found.size()); >>> assertTrue(found.contains(person4)); >>> } >>> >>> I put some logs in the processPutKeyValueCommand method in the >>> *QueryInterceptor* to explain what is happening. >>> >>> *2 threads* >>> Sometimes two threads get involved. >>> >>> = Thread 72 First (or second) call >>> It happens from a non local Node. The so the shouldModifyIndexes says >>> "no, you should not modify any index" because the >>> IndexModificationStrategy is set to "LOCAL ONLY". [1] >>> >>> 72 ctx.getOrigin() = ClusteredCacheWithElasticsearc >>> hIndexManagerIT-NodeB-19565 >>> 72 should modify false >>> 72 previousValue null >>> 72 putValue Person{name='newGoat', blurb='eats something', age=42, >>> dateOfGraduation=null} // value in the command >>> 72 contextValue Person{name='newGoat', blurb='eats something', age=42, >>> dateOfGraduation=null} //value in the invocation context >>> >>> = Thread 48 Second (or first) call >>> the origin is null, and this is considered as a LOCAL in the >>> SingleKeyNonTxInvocationContext. [2] In this case, the index is >>> modified correctly, the value in the context has already been set up by the >>> PutKeyValueCommand and the index get's correctly updated. >>> >>> 48 ctx.getOrigin() = null >>> 48 should modify true >>> 48 previousValue null >>> 48 putValue Person{name='newGoat', blurb='eats something', age=42, >>> dateOfGraduation=null} >>> 48 contextValue Person{name='newGoat', blurb='eats something', age=42, >>> dateOfGraduation=null} >>> >>> And everything is ok. Everything is fine too in the case of a compute >>> method instead of the put method. >>> >>> But sometimes, this is not executed like that. >>> >>> *3 threads* >>> >>> What is a bit more weird to me is this second scenario where the >>> commands are executed both from non local nodes (A and B). And so the index >>> is not updated. >>> But just later, another thread get's involved and calls the >>> QueryInterceptor with a invocation context where the command has not been >>> executed (the value is not inside the context and the debugger does not >>> enter in the perform method, this has happened just twice before). This >>> call is coming like from a callback? in the QueueAsyncInvocationStage. >>> >>> 80 ctx.getOrigin() = ClusteredCacheWithElasticsearc >>> hIndexManagerIT-NodeA-65110 >>> 80 should modify false >>> 80 prev null >>> 80 putValue Person{name='newGoat', blurb='eats something', age=42, >>> dateOfGraduation=null} >>> 80 contextValue Person{name='newGoat', blurb='eats something', age=42, >>> dateOfGraduation=null} >>> >>> 38 ctx.getOrigin() = ClusteredCacheWithElasticsearc >>> hIndexManagerIT-NodeB-35919 >>> 38 should modify false >>> 38 prev null >>> 38 putValue Person{name='newGoat', blurb='eats something', age=42, >>> dateOfGraduation=null} >>> 38 contextValue Person{name='newGoat', blurb='eats something', age=42, >>> dateOfGraduation=null} >>> >>> 48 ctx.getOrigin() = null >>> 48 should modify true >>> 48 prev null >>> 48 putValue Person{name='newGoat', blurb='eats something', age=42, >>> dateOfGraduation=null} >>> 48 contextValue null >>> >>> >>> This execution works perfectly with PutKeyValueCommand. But don't work >>> wth compute. >>> >>> The "computed value" is not inside the Command like put, replace or >>> others. It is computed in the perform method (if needed). So, the first >>> time the command is executed in A, the computed value is in the context, >>> but the index is not updated. Second call, executed in B, value in context, >>> but the index is not updated. The magic callback is executed, but the >>> computed value is nowhere because the command is not executed a third time, >>> so the context is null. >>> >>> Can somebody please give me some light on this and explain to me what am >>> I missing ? Other tests are failing for the same problem, >>> like org.infinispan.query.blackbox.ClusteredCacheWithInfinis >>> panDirectoryTest >>> >>> Thank you very much for your help ! >>> >>> Katia >>> >>> [1] https://github.com/infinispan/infinispan/blob/master/que >>> ry/src/main/java/org/infinispan/query/backend/IndexModificat >>> ionStrategy.java#L50 >>> [2] https://github.com/infinispan/infinispan/blob/master/cor >>> e/src/main/java/org/infinispan/context/SingleKeyNonTxInvocat >>> ionContext.java#L39 >>> >>> >>> _______________________________________________ >>> infinispan-dev mailing list >>> infinispan-dev@lists.jboss.org >>> https://lists.jboss.org/mailman/listinfo/infinispan-dev >>> >> >> >> _______________________________________________ >> infinispan-dev mailing list >> infinispan-dev@lists.jboss.org >> https://lists.jboss.org/mailman/listinfo/infinispan-dev >> > > > _______________________________________________ > infinispan-dev mailing list > infinispan-dev@lists.jboss.org > https://lists.jboss.org/mailman/listinfo/infinispan-dev >
_______________________________________________ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev