use of com.apple.foundationdb.FDBException in project fdb-record-layer by FoundationDB.
the class RangeSetTest method concurrentWithInsert.
// Test out a few of the wild and wacky things that can happen when there are insertions going concurrently.
@Test
@Tag(Tags.Slow)
public void concurrentWithInsert() {
final List<byte[]> keys = createKeys();
final List<Range> ranges = new ArrayList<>();
// Two disjoint ranges -- both should succeed.
Transaction tr1 = db.createTransaction();
Transaction tr2 = db.createTransaction();
Range r1 = new Range(new byte[] { 0x01 }, new byte[] { 0x02 });
Range r2 = new Range(new byte[] { 0x02 }, new byte[] { 0x03 });
CompletableFuture<Boolean> future1 = rs.insertRange(tr1, r1);
CompletableFuture<Boolean> future2 = rs.insertRange(tr2, r2);
assertTrue(future1.join(), "Range 1 did not do insertion.");
assertTrue(future2.join(), "Range 2 did not do insertion.");
tr1.commit().join();
tr2.commit().join();
ranges.add(r1);
ranges.add(r2);
checkConsistent(ranges, keys);
checkIncreasing();
// Two non-disjoint ranges. The second should fail.
tr1 = db.createTransaction();
tr2 = db.createTransaction();
r1 = new Range(new byte[] { 0x03 }, new byte[] { 0x05 });
r2 = new Range(new byte[] { 0x04 }, new byte[] { 0x06 });
future1 = rs.insertRange(tr1, r1);
future2 = rs.insertRange(tr2, r2);
assertTrue(future1.join(), "Range 1 did not do insertion");
assertTrue(future2.join(), "Range 2 did not do insertion");
tr1.commit().join();
tr2.commit().handle((vignore, e) -> {
assertNotNull(e, "No error thrown from commit");
assertTrue(e instanceof FDBException, "Non-FDBException " + e.toString());
FDBException fdbe = (FDBException) e;
assertEquals(FDBError.NOT_COMMITTED.code(), fdbe.getCode(), "Did not get not-committed error.");
return vignore;
}).join();
ranges.add(r1);
checkConsistent(ranges, keys);
checkIncreasing();
// Read during write - the reads in the range should fail.
r1 = new Range(new byte[] { 0x07 }, new byte[] { 0x08 });
List<byte[]> specificKeys = Arrays.asList(new byte[] { 0x06, (byte) 0xff }, new byte[] { 0x07 }, new byte[] { 0x07, 0x00 }, new byte[] { 0x07, 0x10 }, new byte[] { 0x08 }, new byte[] { 0x08, 0x00 }, new byte[] { 0x08, 0x10 }, new byte[] { 0x09 });
tr1 = db.createTransaction();
List<Transaction> transactions = specificKeys.stream().map(ignore -> db.createTransaction()).collect(Collectors.toList());
// Add write conflict ranges to each key so that they are not read only.
transactions.forEach(tr -> tr.addWriteConflictKey(DEADC0DE));
future1 = rs.insertRange(tr1, r1);
List<CompletableFuture<Boolean>> futures = new ArrayList<>();
for (int i = 0; i < specificKeys.size(); i++) {
futures.add(rs.contains(transactions.get(i), specificKeys.get(i)));
}
assertTrue(future1.join(), "Range 1 did not do insertion");
futures.forEach(future -> assertFalse(future.join(), "Key should not be present"));
tr1.commit().join();
Range range = r1;
for (int i = 0; i < transactions.size(); i++) {
final int index = i;
transactions.get(i).commit().handle((vignore, e) -> {
byte[] key = specificKeys.get(index);
String repr = ByteArrayUtil.printable(key);
if (ByteArrayUtil.compareUnsigned(range.begin, key) <= 0 && ByteArrayUtil.compareUnsigned(key, range.end) < 0) {
assertNotNull(e, "No error from commit when key is " + repr);
assertTrue(e instanceof FDBException, "Non-FDBException " + e.toString() + " with key " + repr);
FDBException fdbe = (FDBException) e;
assertEquals(FDBError.NOT_COMMITTED.code(), fdbe.getCode(), "Did not get non-committed error when key is " + repr);
} else {
assertNull(e, "Error when key is " + repr);
}
return vignore;
}).join();
}
ranges.add(r1);
checkConsistent(ranges, keys);
checkIncreasing();
}
use of com.apple.foundationdb.FDBException in project lionrock by panghy.
the class GrpcAsyncIteratorTest method testIterator_failure.
@Test
public void testIterator_failure() {
GrpcAsyncIterator.RemovalCallback<com.apple.foundationdb.KeyValue> removalCallback = mock(GrpcAsyncIterator.RemovalCallback.class);
GrpcAsyncIterator<com.apple.foundationdb.KeyValue, GetRangeResponse> iterator = new GrpcAsyncIterator<>(removalCallback, resp -> resp.getKeyValuesList().stream().map(x -> new com.apple.foundationdb.KeyValue(x.getKey().toByteArray(), x.getValue().toByteArray())), NamedCompletableFuture::new, GetRangeResponse::getDone);
// add 1st and 2nd element.
CompletableFuture<Boolean> cf = iterator.onHasNext();
assertFalse(cf.isDone());
iterator.accept(GetRangeResponse.newBuilder().addKeyValues(KeyValue.newBuilder().setKey(ByteString.copyFrom("hello", StandardCharsets.UTF_8)).setValue(ByteString.copyFrom("world", StandardCharsets.UTF_8)).build()).addKeyValues(KeyValue.newBuilder().setKey(ByteString.copyFrom("hello2", StandardCharsets.UTF_8)).setValue(ByteString.copyFrom("world2", StandardCharsets.UTF_8)).build()).build());
assertTrue(cf.isDone());
assertTrue(iterator.hasNext());
com.apple.foundationdb.KeyValue next = iterator.next();
assertArrayEquals("hello".getBytes(StandardCharsets.UTF_8), next.getKey());
cf = iterator.onHasNext();
assertTrue(cf.isDone());
assertTrue(iterator.hasNext());
next = iterator.next();
assertArrayEquals("hello2".getBytes(StandardCharsets.UTF_8), next.getKey());
cf = iterator.onHasNext();
assertFalse(cf.isDone());
iterator.accept(OperationFailureResponse.newBuilder().setCode(123).setMessage("failed").build());
assertTrue(cf.isCompletedExceptionally());
FDBException join = (FDBException) cf.handle((aBoolean, throwable) -> throwable).join();
assertEquals(123, join.getCode());
assertEquals("failed", join.getMessage());
// does not change the state.
iterator.accept(GetRangeResponse.newBuilder().addKeyValues(KeyValue.newBuilder().setKey(ByteString.copyFrom("hello", StandardCharsets.UTF_8)).setValue(ByteString.copyFrom("world", StandardCharsets.UTF_8)).build()).addKeyValues(KeyValue.newBuilder().setKey(ByteString.copyFrom("hello2", StandardCharsets.UTF_8)).setValue(ByteString.copyFrom("world2", StandardCharsets.UTF_8)).build()).build());
cf = iterator.onHasNext();
assertTrue(cf.isCompletedExceptionally());
}
use of com.apple.foundationdb.FDBException in project lionrock by panghy.
the class RemoteRecordLayerTests method setupConnection.
@BeforeEach
public void setupConnection() {
logger.info("setupConnection()");
RemoteFDBDatabaseFactory factory = new RemoteFDBDatabaseFactory(channel, "RemoteRecordLayerTests");
this.fdb = factory.getDatabase();
this.fdb.setAsyncToSyncExceptionMapper((ex, event) -> {
if (ex instanceof ExecutionException || ex instanceof CompletionException) {
ex = ex.getCause();
}
if (ex instanceof FDBException) {
FDBException fdbex = (FDBException) ex;
switch(FDBError.fromCode(fdbex.getCode())) {
case TRANSACTION_TOO_OLD:
return (new FDBExceptions.FDBStoreTransactionIsTooOldException(fdbex));
case NOT_COMMITTED:
return (new FDBExceptions.FDBStoreTransactionConflictException(fdbex));
case TRANSACTION_TIMED_OUT:
return (new FDBExceptions.FDBStoreTransactionTimeoutException(fdbex));
case TRANSACTION_TOO_LARGE:
return (new FDBExceptions.FDBStoreTransactionSizeException(fdbex));
case KEY_TOO_LARGE:
return (new FDBExceptions.FDBStoreKeySizeException(fdbex));
case VALUE_TOO_LARGE:
return (new FDBExceptions.FDBStoreValueSizeException(fdbex));
default:
return fdbex.isRetryable() ? (new FDBExceptions.FDBStoreRetriableException(fdbex)) : (new FDBExceptions.FDBStoreException(fdbex));
}
} else if (ex instanceof RuntimeException) {
return (RuntimeException) ex;
} else {
return ex instanceof InterruptedException ? (new RecordCoreInterruptedException(ex.getMessage(), new Object[] { ex })) : (new RecordCoreException(ex.getMessage(), ex));
}
});
final KeySpace keySpace = new KeySpace(new DirectoryLayerDirectory("application").addSubdirectory(new KeySpaceDirectory("environment", KeySpaceDirectory.KeyType.STRING)));
this.path = keySpace.path("application", "record-layer-sample").add("environment", "demo");
this.fdb.runAsync(path::deleteAllDataAsync).join();
RecordMetaDataBuilder rmdBuilder = RecordMetaData.newBuilder().setRecords(SampleProto.getDescriptor());
rmdBuilder.getRecordType("Customer").setPrimaryKey(concatenateFields("last_name", "first_name", "customer_id"));
rmdBuilder.addUniversalIndex(new Index("globalCount", new GroupingKeyExpression(EmptyKeyExpression.EMPTY, 0), IndexTypes.COUNT));
rmdBuilder.addIndex("Customer", new Index("first_name", field("first_name"), IndexTypes.VALUE));
rmdBuilder.addIndex("Customer", new Index("email_address", field("email_address", KeyExpression.FanType.FanOut), IndexTypes.VALUE));
rmdBuilder.addIndex("Customer", new Index("preference_tag", field("preference_tag", KeyExpression.FanType.Concatenate), IndexTypes.VALUE));
rmdBuilder.addIndex("Customer", new Index("preference_tag_count", new GroupingKeyExpression(field("preference_tag", KeyExpression.FanType.FanOut), 0), IndexTypes.COUNT));
rmdBuilder.addIndex("Customer", new Index("order", field("order", KeyExpression.FanType.FanOut).nest("quantity"), IndexTypes.VALUE));
rmdBuilder.addIndex("Customer", new Index("item_quantity_sum", new GroupingKeyExpression(field("order", KeyExpression.FanType.FanOut).nest(concatenateFields("item_id", "quantity")), 1), IndexTypes.SUM));
RecordMetaData rmd = rmdBuilder.getRecordMetaData();
this.recordStoreBuilder = FDBRecordStore.newBuilder().setMetaDataProvider(rmd).setKeySpacePath(path);
RecordStoreState storeState = fdb.run(cx -> {
FDBRecordStore store = recordStoreBuilder.copyBuilder().setContext(cx).createOrOpen();
return store.getRecordStoreState();
});
logger.info("storeState: " + storeState.toString());
Set<String> disabledIndexNames = storeState.getDisabledIndexNames();
logger.info("disabledIndexNames: " + Joiner.on(",").join(disabledIndexNames));
AsyncUtil.whenAll(storeState.getDisabledIndexNames().stream().map(indexName -> {
// Build this index. It will begin the background job and return a future
// that will complete when the index is ready for querying.
OnlineIndexer indexBuilder = OnlineIndexer.newBuilder().setDatabase(fdb).setRecordStoreBuilder(recordStoreBuilder).setIndex(indexName).build();
return indexBuilder.buildIndexAsync().whenComplete((vignore, eignore) -> {
logger.info("Finished Rebuilding Index: " + indexName);
indexBuilder.close();
});
}).collect(Collectors.toList())).join();
writeRecords();
}
Aggregations