[
https://issues.apache.org/jira/browse/IGNITE-642?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15208540#comment-15208540
]
Yakov Zhdanov commented on IGNITE-642:
--------------------------------------
Vlad,
# I think you should use IgniteException in method signature rather than
IgniteInterruptedException. The later one is for wrapping standard
InterruptedException. You can see IgniteQueue method signatures. Btw, I like
your javadocs. I find them much better than just inheritance.
# It seems that tests for lock are not checked by TC (seems same applies for
semaphore). Since we have a huge amount of tests we need to manually add tests
to suites to run them in separate plans on TC. Please add lock tests to
{{IgniteCacheDataStructuresSelfTestSuite}}. I will do that for Semaphore in
master.
# Will it make sense to test {{failoverSafe}} flag more thoroughly, i.e. not
just log the expected exception but fail if exception is not thrown? Agree?
# Vlad, it seems there is an issue with callbacks (I believe something like
that may be in Semaphore, can you please check?). I have wrote a program
(below) and I see that one node significantly dominates in acquiring lock. You
can find my output below as well. The reason of this behavior I suspect is that
onUpdate() callback is called in the same order. This is how continuous query
works. Can you please think it over and suggest a solution? Maybe it is
possible to have queue in lock's global state and each node should check
whether it can start the global state update or not? I.e. whenever node gets
notification it should check the queue from head, eliminate all the candidates
from failed nodes and if local candidate is the first one, then start
transaction and update the state. Will it work?
{noformat}
public static void main(String[] args) {
final AtomicBoolean b = new AtomicBoolean();
int threadCnt = 8;
final CyclicBarrier barrier = new CyclicBarrier(threadCnt);
final Lock globalLock = new ReentrantLock();
final boolean useIgniteLock = true;
for (int i = 0; i < threadCnt; i++) {
new Thread(
new Runnable() {
@Override public void run() {
Lock l;
if (useIgniteLock) {
TcpCommunicationSpi commSpi = new
TcpCommunicationSpi();
commSpi.setSharedMemoryPort(-1);
Ignite ignite = Ignition.start(
new IgniteConfiguration()
.setGridName(Thread.currentThread().getName())
.setLocalHost("127.0.0.1")
.setCommunicationSpi(commSpi));
l = ignite.reentrantLock(
"lock",
true,
true);
}
else
l = globalLock;
try {
barrier.await();
}
catch (Exception e) {
throw new RuntimeException();
}
System.out.println("Starting iterations.");
for (int i = 1; ; i++) {
l.lock();
try {
if (!b.compareAndSet(false, true))
throw new RuntimeException();
if ((i & 1023) == 0)
System.out.println("Finished iteration [i="
+ i +
", thread=" +
Thread.currentThread().getName() + ']');
b.set(false);
}
finally {
l.unlock();
}
}
}
}
).start();
}
}
{noformat}
output (see how thread-6 dominates over other)
{noformat}
[18:57:39] Topology snapshot [ver=8, servers=8, clients=0, CPUs=8, heap=3.6GB]
Starting iterations.
Starting iterations.
Starting iterations.
Starting iterations.
Starting iterations.
Starting iterations.
Starting iterations.
Starting iterations.
Finished iteration [i=1024, thread=Thread-6]
Finished iteration [i=2048, thread=Thread-6]
Finished iteration [i=3072, thread=Thread-6]
Finished iteration [i=4096, thread=Thread-6]
Finished iteration [i=5120, thread=Thread-6]
Finished iteration [i=1024, thread=Thread-4]
Finished iteration [i=1024, thread=Thread-3]
Finished iteration [i=6144, thread=Thread-6]
Finished iteration [i=1024, thread=Thread-1]
Finished iteration [i=1024, thread=Thread-2]
Finished iteration [i=7168, thread=Thread-6]
Finished iteration [i=8192, thread=Thread-6]
Finished iteration [i=9216, thread=Thread-6]
Finished iteration [i=1024, thread=Thread-0]
Finished iteration [i=10240, thread=Thread-6]
Finished iteration [i=1024, thread=Thread-7]
Finished iteration [i=2048, thread=Thread-4]
Finished iteration [i=11264, thread=Thread-6]
Finished iteration [i=12288, thread=Thread-6]
Finished iteration [i=2048, thread=Thread-3]
Finished iteration [i=2048, thread=Thread-1]
Finished iteration [i=13312, thread=Thread-6]
Finished iteration [i=1024, thread=Thread-5]
Finished iteration [i=2048, thread=Thread-2]
Finished iteration [i=14336, thread=Thread-6]
Finished iteration [i=15360, thread=Thread-6]
Finished iteration [i=3072, thread=Thread-4]
Finished iteration [i=16384, thread=Thread-6]
Finished iteration [i=17408, thread=Thread-6]
Finished iteration [i=18432, thread=Thread-6]
Finished iteration [i=3072, thread=Thread-3]
{noformat}
> Implement IgniteReentrantLock data structure
> --------------------------------------------
>
> Key: IGNITE-642
> URL: https://issues.apache.org/jira/browse/IGNITE-642
> Project: Ignite
> Issue Type: Sub-task
> Components: data structures
> Affects Versions: 1.6
> Reporter: Dmitriy Setrakyan
> Assignee: Vladisav Jelisavcic
> Labels: features
> Fix For: 1.6
>
>
> We need to add {{IgniteReentrantLock}} data structure in addition to other
> data structures provided by Ignite. {{IgniteReentrantLock}} should have
> similar API to {{java.util.concurrent.locks.ReentrantLock}} class in JDK.
> As an example, you can see how
> [IgniteCountDownLatch|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/IgniteCountDownLatch.java]
> is implemented in
> [GridCacheCountDownLatchImpl|https://github.com/apache/incubator-ignite/blob/master/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridCacheCountDownLatchImpl.java]
> class.
> In general we need to have an entity in ATOMIC cache storing lock-owner
> identifier together with a queue of waiters.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)