Search in sources :

Example 1 with CommitCallback

use of cz.o2.proxima.direct.core.CommitCallback 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);
}
Also used : Arrays(java.util.Arrays) Transaction(cz.o2.proxima.direct.transaction.TransactionalOnlineAttributeWriter.Transaction) ConfigConstants(cz.o2.proxima.repository.ConfigConstants) EntityDescriptor(cz.o2.proxima.repository.EntityDescriptor) Random(java.util.Random) ByteBuffer(java.nio.ByteBuffer) Wildcard(cz.o2.proxima.repository.EntityAwareAttributeDescriptor.Wildcard) ExceptionUtils(cz.o2.proxima.util.ExceptionUtils) CachedView(cz.o2.proxima.direct.view.CachedView) StreamElement(cz.o2.proxima.storage.StreamElement) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) TransformationRunner(cz.o2.proxima.util.TransformationRunner) Map(java.util.Map) After(org.junit.After) TransactionResourceManager(cz.o2.proxima.direct.transaction.TransactionResourceManager) Optionals(cz.o2.proxima.util.Optionals) Flags(cz.o2.proxima.transaction.Response.Flags) BlockingQueue(java.util.concurrent.BlockingQueue) ObserveHandle(cz.o2.proxima.direct.commitlog.ObserveHandle) UUID(java.util.UUID) CommitCallback(cz.o2.proxima.direct.core.CommitCallback) Collectors(java.util.stream.Collectors) ArrayBlockingQueue(java.util.concurrent.ArrayBlockingQueue) CountDownLatch(java.util.concurrent.CountDownLatch) List(java.util.List) Slf4j(lombok.extern.slf4j.Slf4j) KeyValue(cz.o2.proxima.direct.randomaccess.KeyValue) Response(cz.o2.proxima.transaction.Response) Optional(java.util.Optional) DirectDataOperator(cz.o2.proxima.direct.core.DirectDataOperator) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) OnlineAttributeWriter(cz.o2.proxima.direct.core.OnlineAttributeWriter) AtomicReference(java.util.concurrent.atomic.AtomicReference) ArrayList(java.util.ArrayList) ClientTransactionManager(cz.o2.proxima.direct.transaction.ClientTransactionManager) Regular(cz.o2.proxima.repository.EntityAwareAttributeDescriptor.Regular) ConfigFactory(com.typesafe.config.ConfigFactory) ExecutorService(java.util.concurrent.ExecutorService) DeclaredThreadSafe(cz.o2.proxima.annotations.DeclaredThreadSafe) TransactionalOnlineAttributeWriter(cz.o2.proxima.direct.transaction.TransactionalOnlineAttributeWriter) Before(org.junit.Before) Repository(cz.o2.proxima.repository.Repository) Config(com.typesafe.config.Config) Assert.assertTrue(org.junit.Assert.assertTrue) KeyAttribute(cz.o2.proxima.transaction.KeyAttribute) KeyAttributes(cz.o2.proxima.transaction.KeyAttributes) Test(org.junit.Test) TimeUnit(java.util.concurrent.TimeUnit) TransactionRejectedException(cz.o2.proxima.direct.transaction.TransactionalOnlineAttributeWriter.TransactionRejectedException) Collections(java.util.Collections) Assert.assertEquals(org.junit.Assert.assertEquals) KeyValue(cz.o2.proxima.direct.randomaccess.KeyValue) KeyAttributes(cz.o2.proxima.transaction.KeyAttributes) StreamElement(cz.o2.proxima.storage.StreamElement) KeyAttribute(cz.o2.proxima.transaction.KeyAttribute) CommitCallback(cz.o2.proxima.direct.core.CommitCallback) CountDownLatch(java.util.concurrent.CountDownLatch) Response(cz.o2.proxima.transaction.Response) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ArrayBlockingQueue(java.util.concurrent.ArrayBlockingQueue)

Example 2 with CommitCallback

use of cz.o2.proxima.direct.core.CommitCallback 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);
}
Also used : Arrays(java.util.Arrays) Transaction(cz.o2.proxima.direct.transaction.TransactionalOnlineAttributeWriter.Transaction) ConfigConstants(cz.o2.proxima.repository.ConfigConstants) EntityDescriptor(cz.o2.proxima.repository.EntityDescriptor) Random(java.util.Random) ByteBuffer(java.nio.ByteBuffer) Wildcard(cz.o2.proxima.repository.EntityAwareAttributeDescriptor.Wildcard) ExceptionUtils(cz.o2.proxima.util.ExceptionUtils) CachedView(cz.o2.proxima.direct.view.CachedView) StreamElement(cz.o2.proxima.storage.StreamElement) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) TransformationRunner(cz.o2.proxima.util.TransformationRunner) Map(java.util.Map) After(org.junit.After) TransactionResourceManager(cz.o2.proxima.direct.transaction.TransactionResourceManager) Optionals(cz.o2.proxima.util.Optionals) Flags(cz.o2.proxima.transaction.Response.Flags) BlockingQueue(java.util.concurrent.BlockingQueue) ObserveHandle(cz.o2.proxima.direct.commitlog.ObserveHandle) UUID(java.util.UUID) CommitCallback(cz.o2.proxima.direct.core.CommitCallback) Collectors(java.util.stream.Collectors) ArrayBlockingQueue(java.util.concurrent.ArrayBlockingQueue) CountDownLatch(java.util.concurrent.CountDownLatch) List(java.util.List) Slf4j(lombok.extern.slf4j.Slf4j) KeyValue(cz.o2.proxima.direct.randomaccess.KeyValue) Response(cz.o2.proxima.transaction.Response) Optional(java.util.Optional) DirectDataOperator(cz.o2.proxima.direct.core.DirectDataOperator) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) OnlineAttributeWriter(cz.o2.proxima.direct.core.OnlineAttributeWriter) AtomicReference(java.util.concurrent.atomic.AtomicReference) ArrayList(java.util.ArrayList) ClientTransactionManager(cz.o2.proxima.direct.transaction.ClientTransactionManager) Regular(cz.o2.proxima.repository.EntityAwareAttributeDescriptor.Regular) ConfigFactory(com.typesafe.config.ConfigFactory) ExecutorService(java.util.concurrent.ExecutorService) DeclaredThreadSafe(cz.o2.proxima.annotations.DeclaredThreadSafe) TransactionalOnlineAttributeWriter(cz.o2.proxima.direct.transaction.TransactionalOnlineAttributeWriter) Before(org.junit.Before) Repository(cz.o2.proxima.repository.Repository) Config(com.typesafe.config.Config) Assert.assertTrue(org.junit.Assert.assertTrue) KeyAttribute(cz.o2.proxima.transaction.KeyAttribute) KeyAttributes(cz.o2.proxima.transaction.KeyAttributes) Test(org.junit.Test) TimeUnit(java.util.concurrent.TimeUnit) TransactionRejectedException(cz.o2.proxima.direct.transaction.TransactionalOnlineAttributeWriter.TransactionRejectedException) Collections(java.util.Collections) Assert.assertEquals(org.junit.Assert.assertEquals) KeyValue(cz.o2.proxima.direct.randomaccess.KeyValue) KeyAttributes(cz.o2.proxima.transaction.KeyAttributes) StreamElement(cz.o2.proxima.storage.StreamElement) KeyAttribute(cz.o2.proxima.transaction.KeyAttribute) CommitCallback(cz.o2.proxima.direct.core.CommitCallback) CountDownLatch(java.util.concurrent.CountDownLatch) Response(cz.o2.proxima.transaction.Response) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ArrayBlockingQueue(java.util.concurrent.ArrayBlockingQueue)

Example 3 with CommitCallback

use of cz.o2.proxima.direct.core.CommitCallback in project proxima-platform by O2-Czech-Republic.

the class TransactionalOnlineAttributeWriter method write.

@Override
public synchronized void write(StreamElement data, CommitCallback statusCallback) {
    // this means start transaction with the single KeyAttribute as input and then
    // commit that transaction right away
    executor.execute(() -> {
        try (Transaction t = begin()) {
            @Nullable String suffix = data.getAttributeDescriptor().isWildcard() ? data.getAttribute().substring(data.getAttributeDescriptor().toAttributePrefix().length()) : null;
            KeyAttribute outputKeyAttribute = KeyAttributes.ofAttributeDescriptor(data.getEntityDescriptor(), data.getKey(), data.getAttributeDescriptor(), Long.MAX_VALUE, suffix);
            t.update(Collections.singletonList(outputKeyAttribute));
            t.commitWrite(Collections.singletonList(data), statusCallback);
        } catch (TransactionRejectedException e) {
            statusCallback.commit(false, e);
        }
    });
}
Also used : KeyAttribute(cz.o2.proxima.transaction.KeyAttribute) Nullable(javax.annotation.Nullable)

Example 4 with CommitCallback

use of cz.o2.proxima.direct.core.CommitCallback in project proxima-platform by O2-Czech-Republic.

the class TransactionResourceManager method writeResponseAndUpdateState.

@Override
public void writeResponseAndUpdateState(String transactionId, State updateState, String responseId, Response response, CommitCallback callback) {
    CachedTransaction cachedTransaction = openTransactionMap.get(transactionId);
    if (cachedTransaction != null) {
        DirectAttributeFamilyDescriptor responseFamily = cachedTransaction.getResponseFamily();
        DirectAttributeFamilyDescriptor stateFamily = cachedTransaction.getStateFamily();
        final OnlineAttributeWriter writer = cachedTransaction.getCommitWriter();
        final CachedView stateView = cachedTransaction.getStateView();
        long now = System.currentTimeMillis();
        StreamElement stateUpsert = getStateDesc().upsert(transactionId, now, updateState);
        Commit commit = Commit.of(Arrays.asList(new Commit.TransactionUpdate(stateFamily.getDesc().getName(), stateUpsert), new Commit.TransactionUpdate(responseFamily.getDesc().getName(), getResponseDesc().upsert(transactionId, responseId, now, response))));
        synchronized (stateView) {
            ensureTransactionOpen(transactionId, updateState);
            stateView.cache(stateUpsert);
        }
        synchronized (writer) {
            writer.write(getCommitDesc().upsert(transactionId, System.currentTimeMillis(), commit), callback);
        }
    } else {
        log.warn("Transaction {} is not open, don't have a writer to return response {}", transactionId, response);
        callback.commit(true, null);
    }
}
Also used : DirectAttributeFamilyDescriptor(cz.o2.proxima.direct.core.DirectAttributeFamilyDescriptor) CachedView(cz.o2.proxima.direct.view.CachedView) Commit(cz.o2.proxima.transaction.Commit) OnlineAttributeWriter(cz.o2.proxima.direct.core.OnlineAttributeWriter) StreamElement(cz.o2.proxima.storage.StreamElement)

Example 5 with CommitCallback

use of cz.o2.proxima.direct.core.CommitCallback in project proxima-platform by O2-Czech-Republic.

the class CommitCallback method afterNumCommits.

/**
 * Create new {@link CommitCallback} that will commit the delegate after
 *
 * <ul>
 *   <li>{@code numCommits} successful commits as successful, or
 *   <li>after first error as failed
 * </ul>
 *
 * @param numCommits
 * @param delegate
 * @return
 */
static CommitCallback afterNumCommits(int numCommits, CommitCallback delegate) {
    Preconditions.checkState(numCommits > 0, "numCommits must be positive, got %s", numCommits);
    AtomicInteger missingCommits = new AtomicInteger(numCommits);
    return (succ, exc) -> {
        if (succ) {
            if (missingCommits.decrementAndGet() == 0) {
                delegate.commit(true, null);
            }
        } else if (missingCommits.get() > 0) {
            missingCommits.set(-1);
            delegate.commit(false, exc);
        }
    };
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Stable(cz.o2.proxima.annotations.Stable) Preconditions(com.google.common.base.Preconditions) AtomicInteger(java.util.concurrent.atomic.AtomicInteger)

Aggregations

StreamElement (cz.o2.proxima.storage.StreamElement)7 CommitCallback (cz.o2.proxima.direct.core.CommitCallback)6 KeyAttribute (cz.o2.proxima.transaction.KeyAttribute)6 ConfigFactory (com.typesafe.config.ConfigFactory)5 DeclaredThreadSafe (cz.o2.proxima.annotations.DeclaredThreadSafe)5 DirectDataOperator (cz.o2.proxima.direct.core.DirectDataOperator)5 Wildcard (cz.o2.proxima.repository.EntityAwareAttributeDescriptor.Wildcard)5 EntityDescriptor (cz.o2.proxima.repository.EntityDescriptor)5 Repository (cz.o2.proxima.repository.Repository)5 KeyAttributes (cz.o2.proxima.transaction.KeyAttributes)5 Response (cz.o2.proxima.transaction.Response)5 ExceptionUtils (cz.o2.proxima.util.ExceptionUtils)5 Optionals (cz.o2.proxima.util.Optionals)5 TransformationRunner (cz.o2.proxima.util.TransformationRunner)5 ArrayList (java.util.ArrayList)5 Collections (java.util.Collections)5 List (java.util.List)5 UUID (java.util.UUID)5 ArrayBlockingQueue (java.util.concurrent.ArrayBlockingQueue)5 BlockingQueue (java.util.concurrent.BlockingQueue)5