[
https://issues.apache.org/jira/browse/CASSANDRA-13149?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16030903#comment-16030903
]
Sylvain Lebresne commented on CASSANDRA-13149:
----------------------------------------------
Your analysis does make sense. The concern with creating one instance per
operation however is that one of the goal here is to avoid ever generating the
same UUID twice, especially among competing operations. Basically, if someone
do 2 concurrent prepend on a given list, we can't guarantee which one will end
up first in the list, but we do want to ensure both elements ends up in the
list, not that one gets thrown away because both operation happen to generate
the same UUID.
Overall, there appears to be 2 problems: 1) the broken reliance on
{{System#currentTimeMillis}} being monotonic and 2) the fact that the way we
use the {{time}} is not thread-safe between operations. For 1), we can do
something like we do in {{UUIDGen}}, basically by having {{getNext}} handle the
case of {{millis > current.millis}} by ignoring {{millis}} and using
{{current.millis}} instead (so if {{System#currentTimeMillis}} goes back in
time, rely on the last time saved until the time catches up to that last saved
value; we probably want to change how we handle the case where {{current.nanos
== 0}} though, by decreasing {{millis}} rather than bailing out and generating
the same time as that's wrong). For 2), I suspect the simplest approach could
be to change {{getNext()}} to be able to general {{n}} values atomically
instead of one. Each operation would then grab as many value it needs upfront
and use them. A minor benefit being that if 2 concurrent prepend are done
concurrently, all of the value from each update would end up "together", which
feels nicer (gives some sense of isolation; we may even want to make this work
for append too).
> AssertionError prepending to a list
> -----------------------------------
>
> Key: CASSANDRA-13149
> URL: https://issues.apache.org/jira/browse/CASSANDRA-13149
> Project: Cassandra
> Issue Type: Bug
> Components: CQL
> Environment: 3.0.8
> Reporter: Steven Warren
>
> Prepending to a list produces the following AssertionError randomly. Changing
> the update to append (and sort in the client) works around the issue.
> {code}
> java.lang.AssertionError: null
> at
> org.apache.cassandra.cql3.Lists$PrecisionTime.getNext(Lists.java:275)
> ~[apache-cassandra-3.0.8.jar:3.0.8]
> at org.apache.cassandra.cql3.Lists$Prepender.execute(Lists.java:430)
> ~[apache-cassandra-3.0.8.jar:3.0.8]
> at
> org.apache.cassandra.cql3.statements.UpdateStatement.addUpdateForKey(UpdateStatement.java:94)
> ~[apache-cassandra-3.0.8.jar:3.0.8]
> at
> org.apache.cassandra.cql3.statements.ModificationStatement.addUpdates(ModificationStatement.java:682)
> ~[apache-cassandra-3.0.8.jar:3.0.8]
> at
> org.apache.cassandra.cql3.statements.ModificationStatement.getMutations(ModificationStatement.java:613)
> ~[apache-cassandra-3.0.8.jar:3.0.8]
> at
> org.apache.cassandra.cql3.statements.ModificationStatement.executeWithoutCondition(ModificationStatement.java:420)
> ~[apache-cassandra-3.0.8.jar:3.0.8]
> at
> org.apache.cassandra.cql3.statements.ModificationStatement.execute(ModificationStatement.java:408)
> ~[apache-cassandra-3.0.8.jar:3.0.8]
> at
> org.apache.cassandra.cql3.QueryProcessor.processStatement(QueryProcessor.java:206)
> ~[apache-cassandra-3.0.8.jar:3.0.8]
> at
> org.apache.cassandra.cql3.QueryProcessor.processPrepared(QueryProcessor.java:487)
> ~[apache-cassandra-3.0.8.jar:3.0.8]
> at
> org.apache.cassandra.cql3.QueryProcessor.processPrepared(QueryProcessor.java:464)
> ~[apache-cassandra-3.0.8.jar:3.0.8]
> at
> org.apache.cassandra.transport.messages.ExecuteMessage.execute(ExecuteMessage.java:130)
> ~[apache-cassandra-3.0.8.jar:3.0.8]
> at
> org.apache.cassandra.transport.Message$Dispatcher.channelRead0(Message.java:507)
> [apache-cassandra-3.0.8.jar:3.0.8]
> at
> org.apache.cassandra.transport.Message$Dispatcher.channelRead0(Message.java:401)
> [apache-cassandra-3.0.8.jar:3.0.8]
> at
> io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105)
> [netty-all-4.0.23.Final.jar:4.0.23.Final]
> at
> io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333)
> [netty-all-4.0.23.Final.jar:4.0.23.Final]
> at
> io.netty.channel.AbstractChannelHandlerContext.access$700(AbstractChannelHandlerContext.java:32)
> [netty-all-4.0.23.Final.jar:4.0.23.Final]
> at
> io.netty.channel.AbstractChannelHandlerContext$8.run(AbstractChannelHandlerContext.java:324)
> [netty-all-4.0.23.Final.jar:4.0.23.Final]
> at
> java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
> [na:1.8.0_101]
> at
> org.apache.cassandra.concurrent.AbstractLocalAwareExecutorService$FutureTask.run(AbstractLocalAwareExecutorService.java:164)
> [apache-cassandra-3.0.8.jar:3.0.8]
> at org.apache.cassandra.concurrent.SEPWorker.run(SEPWorker.java:105)
> [apache-cassandra-3.0.8.jar:3.0.8]
> at java.lang.Thread.run(Thread.java:745) [na:1.8.0_101]
> {code}
--
This message was sent by Atlassian JIRA
(v6.3.15#6346)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]