public Long setnx(String key, String value) { Long added = dynoClient.setnx(key, value); return added; }
public Long setnx(String key, String value) { Long added = dynoClient.setnx(key, value); return added; }
private Integer findAvailableWorkerId(WestIdConfig westIdConfig) { val value = Os.PID_STRING + "x" + Os.IP_STRING + "x" + Os.HOSTNAME; for (long i = 0; i <= westIdConfig.getMaxWorkerId(); ++i) { val found = jedis.setnx(PREFIX_USE + i, value) == 1; if (found) { return (int) i; } } return null; }
@SneakyThrows private Integer tryReuseWorkerId() { val pidWorkerIds = jedis.lrange(PREFIX_PID, 0, -1); if (pidWorkerIds.size() == 0) { return null; } boolean locked = jedis.setnx(PREFIX_LOK, Os.PID_STRING) == 1; if (!locked) { return null; } @Cleanup val i = new Closeable() { @Override public void close() throws IOException { jedis.del(PREFIX_LOK); } }; val workerId = findUsableWorkerId(pidWorkerIds); if (workerId == null) { return null; } jedis.set(PREFIX_USE + workerId, Os.PID_STRING + "x" + Os.IP_STRING + "x" + Os.HOSTNAME); return Integer.parseInt(workerId); }
@Override public Task create(String phase, String status, String clientRequestId) { String taskKey = getClientRequestKey(clientRequestId); String taskId = UUID.randomUUID().toString(); JedisTask task = new JedisTask(taskId, System.currentTimeMillis(), this, ClouddriverHostname.ID, false); addToHistory(DefaultTaskStatus.create(phase, status, TaskState.STARTED), task); set(taskId, task); Long newTask = retry(() -> redisClientDelegate.withCommandsClient(client -> { return client.setnx(taskKey, taskId); }), "Registering task with index"); if (newTask != 0) { return task; } // There's an existing taskId for this key, clean up what we just created and get the existing task addToHistory(DefaultTaskStatus.create(phase, "Duplicate of " + clientRequestId, TaskState.FAILED), task); return getByClientRequestId(clientRequestId); }
private boolean acquireRunKey(String agentType, long timeout) { // This isn't as safe as the vanilla Redis impl because the call isn't atomic, but it's the best we can do until // dynomite adds support for `String set(String key, String value, String nxxx, String expx, long time)` (which // they are working on). String identity = nodeIdentity.getNodeIdentity(); return redisClientDelegate.withCommandsClient(client -> { return Failsafe .with(ACQUIRE_LOCK_RETRY_POLICY) .get(() -> { String response = client.get(agentType); if (response == null && client.setnx(agentType, identity) == 1) { client.pexpireAt(agentType, System.currentTimeMillis() + timeout); return true; } if (client.ttl(agentType) == -1) { log.warn("Detected potential deadlocked agent, removing lock key: " + agentType); client.del(agentType); } return false; }); }); }