{"action":"created","issue":{"url":"https://api.github.com/repos/eclipse/vert.x/issues/2418","repository_url":"https://api.github.com/repos/eclipse/vert.x","labels_url":"https://api.github.com/repos/eclipse/vert.x/issues/2418/labels{/name}","comments_url":"https://api.github.com/repos/eclipse/vert.x/issues/2418/comments","events_url":"https://api.github.com/repos/eclipse/vert.x/issues/2418/events","html_url":"https://github.com/eclipse/vert.x/issues/2418","id":317504158,"number":2418,"title":"Possible deadlock when trying to get multiple locks","user":{"login":"nolequen","id":8845686,"avatar_url":"https://avatars1.githubusercontent.com/u/8845686?v=4","gravatar_id":"","url":"https://api.github.com/users/nolequen","html_url":"https://github.com/nolequen","followers_url":"https://api.github.com/users/nolequen/followers","following_url":"https://api.github.com/users/nolequen/following{/other_user}","gists_url":"https://api.github.com/users/nolequen/gists{/gist_id}","starred_url":"https://api.github.com/users/nolequen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nolequen/subscriptions","organizations_url":"https://api.github.com/users/nolequen/orgs","repos_url":"https://api.github.com/users/nolequen/repos","events_url":"https://api.github.com/users/nolequen/events{/privacy}","received_events_url":"https://api.github.com/users/nolequen/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":16,"created_at":"2018-04-25T07:14:07Z","updated_at":"2018-05-28T15:09:02Z","closed_at":null,"author_association":"CONTRIBUTOR","body":"Here is the code, which illustrates the problem.\r\nThe `Consumer` verticle acuires `lock1` and gets stuck.\r\nI have reproduced the same problem using `HazelcastClusterManager` and `IgniteClusterManager`.\r\n\r\n```java\r\n    Vertx.clusteredVertx(\r\n        new VertxOptions().setClusterManager(new HazelcastClusterManager()),\r\n        result -> {\r\n          final Vertx vertx = result.result();\r\n\r\n          final int messagesToSend = 10;\r\n\r\n          final Consumer consumer = new Consumer();\r\n          vertx.deployVerticle(\r\n              consumer,\r\n              new DeploymentOptions(),\r\n              event -> {\r\n                if (event.succeeded()) {\r\n                  vertx.deployVerticle(\r\n                      new Supplier(messagesToSend),\r\n                      new DeploymentOptions()\r\n                  );\r\n                }\r\n              }\r\n          );\r\n\r\n          vertx.setTimer(\r\n              messagesToSend * DEFAULT_LOCK_TIMEOUT,\r\n              timer -> {\r\n                final long failsNumber = messagesToSend - consumer.counter.sum();\r\n                if (failsNumber != 0) {\r\n                  System.err.println(\"Failed to get \" + failsNumber + \" locks\");\r\n                }\r\n                vertx.close();\r\n              }\r\n          );\r\n        }\r\n    );\r\n```\r\n\r\n```java\r\n  class Supplier extends AbstractVerticle {\r\n    private final long messagesToSend;\r\n\r\n    public Supplier(long messagesToSend) {\r\n      this.messagesToSend = messagesToSend;\r\n    }\r\n\r\n    @Override\r\n    public void start() {\r\n      final LongAdder sent = new LongAdder();\r\n      vertx.setPeriodic(1, timer -> {\r\n        vertx.eventBus().send(TEST_ADDRESS, \"message\");\r\n        sent.increment();\r\n        System.out.println(sent.sum() + \" messages sent\");\r\n        if (sent.sum() >= messagesToSend) {\r\n          vertx.cancelTimer(timer);\r\n        }\r\n      });\r\n    }\r\n  }\r\n```\r\n\r\n```java\r\nclass Consumer extends AbstractVerticle {\r\n    private final LongAdder counter = new LongAdder();\r\n\r\n    @Override\r\n    public void start(Future<Void> startFuture) {\r\n      vertx.eventBus().consumer(\r\n          TEST_ADDRESS,\r\n          event -> {\r\n            vertx.sharedData().getLock(\"lock1\", lock1 -> {\r\n              if (lock1.failed()) {\r\n                System.out.println(\"Failed to get lock1: \" + lock1.cause());\r\n              } else {\r\n                System.out.println(\"Succeeded to get lock1\");\r\n                vertx.sharedData().getLock(\"lock2\", lock2 -> {\r\n                  if (lock2.failed()) {\r\n                    System.out.println(\"Failed to get lock2: \" + lock2.cause());\r\n                  } else {\r\n                    System.out.println(\"Succeeded to get lock2\");\r\n                    counter.increment();\r\n                    System.out.println(counter.sum() + \" messages consumed\");\r\n                    lock2.result().release();\r\n                  }\r\n                  lock1.result().release();\r\n                });\r\n              }\r\n            });\r\n          }\r\n      ).completionHandler(startFuture);\r\n    }\r\n  }\r\n```"},"comment":{"url":"https://api.github.com/repos/eclipse/vert.x/issues/comments/392550845","html_url":"https://github.com/eclipse/vert.x/issues/2418#issuecomment-392550845","issue_url":"https://api.github.com/repos/eclipse/vert.x/issues/2418","id":392550845,"user":{"login":"vietj","id":225674,"avatar_url":"https://avatars2.githubusercontent.com/u/225674?v=4","gravatar_id":"","url":"https://api.github.com/users/vietj","html_url":"https://github.com/vietj","followers_url":"https://api.github.com/users/vietj/followers","following_url":"https://api.github.com/users/vietj/following{/other_user}","gists_url":"https://api.github.com/users/vietj/gists{/gist_id}","starred_url":"https://api.github.com/users/vietj/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vietj/subscriptions","organizations_url":"https://api.github.com/users/vietj/orgs","repos_url":"https://api.github.com/users/vietj/repos","events_url":"https://api.github.com/users/vietj/events{/privacy}","received_events_url":"https://api.github.com/users/vietj/received_events","type":"User","site_admin":false},"created_at":"2018-05-28T15:09:02Z","updated_at":"2018-05-28T15:09:02Z","author_association":"CONTRIBUTOR","body":"@tsegismont my initial thought would be to have ordering per lock which solve the issue we are encountering now and avoid to handle race conditions at the API level (i.e have a Map<String, TaskQueue> of temporary entries in the cluster manager like we do have for concurrent multimap lookup)."}}
{"actor":{"display_login":"vietj"}}