use of cz.o2.proxima.transaction.KeyAttribute in project proxima-platform by O2-Czech-Republic.
the class TransactionIT method swapValueBetween.
private boolean swapValueBetween(String key, String attrA, String attrB, boolean canFailWrite) throws InterruptedException {
long retrySleep = 1;
do {
String transactionId = UUID.randomUUID().toString();
BlockingQueue<Response> responses = new ArrayBlockingQueue<>(1);
Optional<KeyValue<byte[]>> valA = view.get(key, attrA, device);
Optional<KeyValue<byte[]>> valB = view.get(key, attrB, device);
final List<KeyAttribute> fetched = Arrays.asList(valA.isPresent() ? KeyAttributes.ofStreamElement(valA.get()) : KeyAttributes.ofMissingAttribute(user, key, device, device.extractSuffix(attrA)), valB.isPresent() ? KeyAttributes.ofStreamElement(valB.get()) : KeyAttributes.ofMissingAttribute(user, key, device, device.extractSuffix(attrB)));
client.begin(transactionId, (id, resp) -> ExceptionUtils.unchecked(() -> responses.put(resp)), fetched);
Response response = responses.take();
if (response.getFlags() != Flags.OPEN) {
;
TimeUnit.MILLISECONDS.sleep(Math.min(8, retrySleep *= 2));
continue;
}
long sequentialId = response.getSeqId();
final List<StreamElement> updates;
if (valA.isPresent()) {
int currentVal = ByteBuffer.wrap(valA.get().getParsedRequired()).getInt();
updates = updateAttributeAndRemove(sequentialId, key, attrB, attrA, currentVal);
} else {
int currentVal = ByteBuffer.wrap(valB.get().getParsedRequired()).getInt();
updates = updateAttributeAndRemove(sequentialId, key, attrA, attrB, currentVal);
}
client.commit(transactionId, updates.stream().map(KeyAttributes::ofStreamElement).collect(Collectors.toList()));
response = responses.take();
if (response.getFlags() != Flags.COMMITTED) {
TimeUnit.MILLISECONDS.sleep(Math.min(8, retrySleep *= 2));
continue;
}
CountDownLatch latch = new CountDownLatch(1);
AtomicBoolean succeeded = new AtomicBoolean();
CommitCallback callback = (succ, exc) -> {
if (!succ) {
client.rollback(transactionId);
}
succeeded.set(succ);
latch.countDown();
};
if (canFailWrite && random.nextBoolean()) {
callback.commit(false, new RuntimeException("Failed!"));
} else {
CommitCallback multiCallback = CommitCallback.afterNumCommits(updates.size(), callback);
updates.forEach(u -> view.write(u, multiCallback));
}
latch.await();
return succeeded.get();
} while (true);
}
use of cz.o2.proxima.transaction.KeyAttribute in project proxima-platform by O2-Czech-Republic.
the class TransactionIT method removeSingleDevice.
private void removeSingleDevice(int numUsers) throws InterruptedException {
do {
TransactionalOnlineAttributeWriter writer = Optionals.get(direct.getWriter(device)).transactional();
try (Transaction t = writer.begin()) {
String userId = "user" + random.nextInt(numUsers);
List<StreamElement> devices = new ArrayList<>();
view.scanWildcard(userId, device, devices::add);
List<KeyAttribute> keyAttributes = KeyAttributes.ofWildcardQueryElements(user, userId, device, devices);
if (devices.isEmpty()) {
continue;
}
long stamp = System.currentTimeMillis();
t.update(keyAttributes);
String name = device.extractSuffix(devices.get(random.nextInt(devices.size())).getAttribute());
StreamElement deviceUpdate = device.delete(userId, name, stamp);
StreamElement numDevicesUpdate = numDevices.upsert(userId, "all", stamp, devices.size() - 1);
CountDownLatch latch = new CountDownLatch(1);
t.commitWrite(Arrays.asList(deviceUpdate, numDevicesUpdate), (succ, exc) -> latch.countDown());
latch.await();
break;
} catch (TransactionRejectedException e) {
// repeat
}
} while (true);
}
use of cz.o2.proxima.transaction.KeyAttribute in project proxima-platform by O2-Czech-Republic.
the class TransactionIT_Large method writeSingleDevice.
private void writeSingleDevice(int numUsers, boolean intoAll) throws InterruptedException {
String name = UUID.randomUUID().toString();
String userId = "user" + random.nextInt(numUsers);
do {
TransactionalOnlineAttributeWriter writer = Optionals.get(direct.getWriter(device)).transactional();
long stamp = System.currentTimeMillis();
try (Transaction t = writer.begin()) {
List<StreamElement> devices = new ArrayList<>();
view.scanWildcard(userId, device, devices::add);
List<KeyAttribute> keyAttributes = KeyAttributes.ofWildcardQueryElements(user, userId, device, devices);
t.update(keyAttributes);
StreamElement deviceUpdate = device.upsert(userId, name, stamp, new byte[] {});
final StreamElement numDevicesUpdate;
int count = devices.size() + 1;
if (intoAll) {
numDevicesUpdate = numDevices.upsert(userId, "all", stamp, count);
} else {
numDevicesUpdate = numDevices.upsert(userId, String.valueOf(count), stamp, count);
}
CountDownLatch latch = new CountDownLatch(1);
t.commitWrite(Arrays.asList(deviceUpdate, numDevicesUpdate), (succ, exc) -> latch.countDown());
latch.await();
break;
} catch (TransactionRejectedException e) {
// repeat
}
} while (true);
}
use of cz.o2.proxima.transaction.KeyAttribute in project proxima-platform by O2-Czech-Republic.
the class TransactionIT_Large method swapValueBetween.
private boolean swapValueBetween(String key, String attrA, String attrB, boolean canFailWrite) throws InterruptedException {
long retrySleep = 1;
do {
String transactionId = UUID.randomUUID().toString();
BlockingQueue<Response> responses = new ArrayBlockingQueue<>(1);
Optional<KeyValue<byte[]>> valA = view.get(key, attrA, device);
Optional<KeyValue<byte[]>> valB = view.get(key, attrB, device);
final List<KeyAttribute> fetched = Arrays.asList(valA.isPresent() ? KeyAttributes.ofStreamElement(valA.get()) : KeyAttributes.ofMissingAttribute(user, key, device, device.extractSuffix(attrA)), valB.isPresent() ? KeyAttributes.ofStreamElement(valB.get()) : KeyAttributes.ofMissingAttribute(user, key, device, device.extractSuffix(attrB)));
client.begin(transactionId, (id, resp) -> ExceptionUtils.unchecked(() -> responses.put(resp)), fetched);
Response response = responses.take();
if (response.getFlags() != Flags.OPEN) {
;
TimeUnit.MILLISECONDS.sleep(Math.min(8, retrySleep *= 2));
continue;
}
long sequentialId = response.getSeqId();
final List<StreamElement> updates;
if (valA.isPresent()) {
int currentVal = ByteBuffer.wrap(valA.get().getParsedRequired()).getInt();
updates = updateAttributeAndRemove(sequentialId, key, attrB, attrA, currentVal);
} else {
int currentVal = ByteBuffer.wrap(valB.get().getParsedRequired()).getInt();
updates = updateAttributeAndRemove(sequentialId, key, attrA, attrB, currentVal);
}
client.commit(transactionId, updates.stream().map(KeyAttributes::ofStreamElement).collect(Collectors.toList()));
response = responses.take();
if (response.getFlags() != Flags.COMMITTED) {
TimeUnit.MILLISECONDS.sleep(Math.min(8, retrySleep *= 2));
continue;
}
CountDownLatch latch = new CountDownLatch(1);
AtomicBoolean succeeded = new AtomicBoolean();
CommitCallback callback = (succ, exc) -> {
if (!succ) {
client.rollback(transactionId);
}
succeeded.set(succ);
latch.countDown();
};
if (canFailWrite && random.nextBoolean()) {
callback.commit(false, new RuntimeException("Failed!"));
} else {
CommitCallback multiCallback = CommitCallback.afterNumCommits(updates.size(), callback);
updates.forEach(u -> view.write(u, multiCallback));
}
latch.await();
return succeeded.get();
} while (true);
}
use of cz.o2.proxima.transaction.KeyAttribute in project proxima-platform by O2-Czech-Republic.
the class TransactionLogObserverTest method testCreateTransactionCommitWithConflictInOutputs.
@Test(timeout = 10000)
public void testCreateTransactionCommitWithConflictInOutputs() throws InterruptedException {
createObserver();
ClientTransactionManager clientManager = direct.getClientTransactionManager();
String t1 = UUID.randomUUID().toString();
String t2 = UUID.randomUUID().toString();
BlockingQueue<Pair<String, Response>> responseQueue = new ArrayBlockingQueue<>(1);
clientManager.begin(t1, ExceptionUtils.uncheckedBiConsumer((k, v) -> responseQueue.put(Pair.of(k, v))), Collections.singletonList(KeyAttributes.ofAttributeDescriptor(user, "u1", userGateways, 1L, "1")));
Pair<String, Response> t1OpenResponse = responseQueue.take();
List<KeyAttribute> t1Outputs = Collections.singletonList(KeyAttributes.ofAttributeDescriptor(user, "user", userGateways, t1OpenResponse.getSecond().getSeqId(), "1"));
clientManager.begin(t2, ExceptionUtils.uncheckedBiConsumer((k, v) -> responseQueue.put(Pair.of(k, v))), // not conflicting with the previous one
Collections.singletonList(KeyAttributes.ofAttributeDescriptor(user, "u2", userGateways, 1L, "1")));
Pair<String, Response> t2OpenResponse = responseQueue.take();
List<KeyAttribute> t2Outputs = Collections.singletonList(KeyAttributes.ofAttributeDescriptor(user, "user", userGateways, t2OpenResponse.getSecond().getSeqId(), "1"));
clientManager.commit(t2, t2Outputs);
Pair<String, Response> response = responseQueue.take();
assertEquals("commit", response.getFirst());
assertEquals(Response.Flags.COMMITTED, response.getSecond().getFlags());
clientManager.commit(t1, t1Outputs);
response = responseQueue.take();
assertEquals("commit", response.getFirst());
assertEquals(Response.Flags.ABORTED, response.getSecond().getFlags());
}
Aggregations