<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Oct 2, 2013 at 12:48 PM, Pedro Ruivo <span dir="ltr">&lt;<a href="mailto:pedro@infinispan.org" target="_blank">pedro@infinispan.org</a>&gt;</span> wrote:<br>


<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><br>
<br>
On 10/02/2013 12:03 AM, Sanne Grinovero wrote:<br>
&gt; I&#39;d love to brainstorm about the clear() operation and what it means<br>
&gt; on Infinispan.<br>
&gt;<br>
&gt; I&#39;m not sure to what extent, but it seems that clear() is designed to<br>
&gt; work in a TX, or even create an implicit transaction if needed, but<br>
&gt; I&#39;m not understanding how that can work.<br></div></blockquote><div><br></div>I think it&#39;s pretty straight-forward to define the semantics of operations after clear(): they should assume that every key in the cache was removed. <br>


<br>True, like Pedro mentioned, the current implementation allows subsequent operations in the same tx to see keys inserted by other txs. But I don&#39;t think fixing that would be harder than ensuring that if a tx inserts key k owned by nodes A and B, clear() from outside the tx either deletes k on A and B or doesn&#39;t delete k on either node.<br>


<div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>
&gt;<br>
&gt; Obviously a clear() operation isn&#39;t listing all keys explicitly.<br>
<br>
</div>(offtopic) like entrySet(), keySet(), values() and iterator() when<br>
executed in a transactional context. however, I think that this<br>
operations are more difficult to handle, because they have to return<br>
consistent data...<br></blockquote><div><br></div><div>I agree, defining how entrySet() and the others should work in a tx seems harder than defining clear().<br><br>Will, I&#39;m guessing your fix for ISPN-3560 still allows entrySet() after clear() to see entries inserted by another tx in the meantime?<br>


</div><div></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div><br>
&gt; Which<br>
&gt; implies that it&#39;s undefined on which keys it&#39;s going to operate when<br>
&gt; it&#39;s fired.. that seems like terribly wrong in a distributed key/value<br>
&gt; store as we can&#39;t possibly freeze the global state and somehow define<br>
&gt; a set of keys which are going to be affected, while an explicit<br>
&gt; enumeration is needed to acquire the needed locks.<br>
<br>
</div>you may not need to explicit acquire the lock for the affected key. you<br>
can use a global lock that is share acquired for write transactions<br>
without clear operation and exclusively acquire for transactions with<br>
clear operation (exactly what I use for Total Order). also, the clear<br>
transactions (i.e. the transactions with clear operation) can also only<br>
acquired the global lock.<br></blockquote><div><br></div><div>+1 for the global lock. It may slow things down a bit in the general case, because every tx will have to acquire it in shared mode, but it will guarantee consistency for clear().<br>


</div><div><br>It still won&#39;t help entrySet() and its brethren...<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div><br>
&gt;<br>
&gt; It might give a nice safe feeling that, when invoking a clear()<br>
&gt; operation in a transaction, I can still abort the transaction to make<br>
&gt; it cancel the operation; that&#39;s the only good part I can think of: we<br>
&gt; can cancel it.<br>
<br>
</div>yep<br></blockquote><div><br></div><div>Wouldn&#39;t it be harder to integrate it with Total Order if it didn&#39;t have a tx?<br><br></div><div>But most of all, I think we have to keep it because it&#39;s a part of the Map interface and a part of JCache&#39;s Cache interface.<br>

</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

<div><br>
&gt;<br>
&gt; I don&#39;t think it has anything to do with consistency though? To make<br>
&gt; sure you&#39;re effectively involving all replicas of all entries in a<br>
&gt; consistent way, a lock would need to be acquired on each affected key,<br>
&gt; which again implies a need to enumerate all keys, including the<br>
&gt; unknown keys which might be hiding in a CacheStore: it&#39;s not enough to<br>
&gt; broadcast the clear() operation to all nodes and have them simply wipe<br>
&gt; their local state as that&#39;s never going to deal correctly<br>
&gt; (consistently) with in-flight transactions working on different nodes<br>
&gt; at different times (I guess enabling Total Order could help but you&#39;d<br>
&gt; need to make it mandatory).<br>
&gt;<br>
<br>
</div>see the comment above about the locks... may not be the most efficient,<br>
but handles the problem.<br></blockquote><div><br></div><div>Note that we need to iterate the keys anyway, in order to fire the CacheEntryRemoved listeners. Even if we optimized it skip the iteration when there are no registered listeners, it would still have to handle the general case.<br>


<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div><br>
&gt; So let&#39;s step back a second and consider what is the use case for<br>
&gt; clear() ? I suspect it&#39;s primarily a method needed during testing, or<br>
&gt; maybe cleanup before a backup is restored (operations), maybe a<br>
&gt; manually activated JMX operation to clear the cache in exceptional<br>
&gt; cases.<br>
<br>
</div>I&#39;m not aware of the uses cases of a clear() operation, but use it as<br>
JMX operation can be a problem in transactional caches (depending the<br>
semantic you have in mind).<br>
<br>
If it is going to clear all the caches (i.e. from all replicas/nodes),<br>
then we have to find a way to set an order with the current transactions<br>
or we will have something some nodes delivering a transaction (say tx1)<br>
before the clear() and other nodes delivering tx1 after the clear(),<br>
leading to an inconsistent state.<br>
<br>
(offtopic) I&#39;m wondering if we have that problem in the current<br>
implementation if tx1 is only insert new keys... in that case, we have<br>
no lock to serialize an order between the clear() and tx1...<br></blockquote><div><br></div><div>I&#39;m pretty sure we do have this problem. We definitely need to add some tests for clear concurrent with other write operations.<br>

<br></div><div>In my view, as long as we&#39;re going to expose a clear() operation in some way, it&#39;s going to be easiest to include it in a tx in transactional caches. Exposing it in some other way is not going to make it any more consistent, although prohibiting other operations in the same tx may make the code a bit simpler.<br>

</div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div><br>
&gt;<br>
&gt; I don&#39;t think there would ever be a need for a clear() operation to<br>
&gt; interact with other transactions, so I&#39;d rather make it illegal to<br>
&gt; invoke a clear() inside a transaction, or simply ignore the<br>
&gt; transactional scope and have an immediate and distributed effect.<br></div></blockquote><div> </div><div>We can&#39;t control whether other transactions are invoked concurrently 
with clear(), so we can&#39;t make that illegal... If you mean interaction 
with other operations in the same transaction, I agree that it&#39;s not 
absolutely necessary to allow them, but I think most of that work has 
already been done. <br><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>
<br>
</div>I think the second solution can make inconsistency data (&quot;or simply<br>
<div>ignore the transactional scope and have an immediate and distributed<br>
</div>effect&quot;)<br></blockquote><div><br></div><div>Maybe that&#39;s the idea? Sanne, do you mean that if clear() were exposed via a different API, it wouldn&#39;t have to provide the same consistency guarantees as regular operations?<br>

</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div><div><br>
&gt;<br>
&gt; I&#39;m likely missing something. What terrible consequences would this have?<br>
&gt;<br>
&gt; Cheers,<br>
&gt; Sanne<br>
&gt; _______________________________________________<br>
&gt; infinispan-dev mailing list<br>
&gt; <a href="mailto:infinispan-dev@lists.jboss.org" target="_blank">infinispan-dev@lists.jboss.org</a><br>
&gt; <a href="https://lists.jboss.org/mailman/listinfo/infinispan-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/infinispan-dev</a><br>
&gt;<br>
_______________________________________________<br>
infinispan-dev mailing list<br>
<a href="mailto:infinispan-dev@lists.jboss.org" target="_blank">infinispan-dev@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/infinispan-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/infinispan-dev</a><br>
</div></div></blockquote></div><br></div></div>