use of com.twitter.distributedlog.service.stream.Stream in project distributedlog by twitter.
the class TestDistributedLogService method testCloseStreamsShouldAbort.
@Test(timeout = 60000)
public void testCloseStreamsShouldAbort() throws Exception {
DistributedLogConfiguration confLocal = newLocalConf();
confLocal.setOutputBufferSize(Integer.MAX_VALUE).setImmediateFlushEnabled(false).setPeriodicFlushFrequencyMilliSeconds(0);
String streamNamePrefix = testName.getMethodName();
DistributedLogServiceImpl localService = createService(serverConf, confLocal);
StreamManagerImpl streamManager = (StreamManagerImpl) localService.getStreamManager();
int numStreams = 10;
int numWrites = 10;
List<Future<WriteResponse>> futureList = Lists.newArrayListWithExpectedSize(numStreams * numWrites);
for (int i = 0; i < numStreams; i++) {
String streamName = streamNamePrefix + "-" + i;
HeartbeatOptions hbOptions = new HeartbeatOptions();
hbOptions.setSendHeartBeatToReader(true);
// make sure the first log segment of each stream created
FutureUtils.result(localService.heartbeatWithOptions(streamName, new WriteContext(), hbOptions));
for (int j = 0; j < numWrites; j++) {
futureList.add(localService.write(streamName, createRecord(i * numWrites + j)));
}
}
assertEquals("There should be " + numStreams + " streams in cache", numStreams, streamManager.getCachedStreams().size());
while (streamManager.getAcquiredStreams().size() < numStreams) {
TimeUnit.MILLISECONDS.sleep(20);
}
for (Stream s : streamManager.getAcquiredStreams().values()) {
StreamImpl stream = (StreamImpl) s;
stream.setStatus(StreamStatus.FAILED);
}
Future<List<Void>> closeResult = localService.closeStreams();
List<Void> closedStreams = Await.result(closeResult);
assertEquals("There should be " + numStreams + " streams closed", numStreams, closedStreams.size());
// all writes should be flushed
for (Future<WriteResponse> future : futureList) {
WriteResponse response = Await.result(future);
assertTrue("Op should fail with " + StatusCode.BK_TRANSMIT_ERROR + " or be rejected : " + response.getHeader().getCode(), StatusCode.BK_TRANSMIT_ERROR == response.getHeader().getCode() || StatusCode.WRITE_EXCEPTION == response.getHeader().getCode() || StatusCode.WRITE_CANCELLED_EXCEPTION == response.getHeader().getCode());
}
// acquired streams should all been removed after we close them
assertTrue("There should be no streams in the acquired cache", streamManager.getAcquiredStreams().isEmpty());
localService.shutdown();
// cached streams wouldn't be removed immediately after streams are closed
// but they should be removed after we shutdown the service
assertTrue("There should be no streams in the cache after shutting down the service", streamManager.getCachedStreams().isEmpty());
}
use of com.twitter.distributedlog.service.stream.Stream in project distributedlog by twitter.
the class TestDistributedLogService method testAcquireStreamsWhenExceedMaxCachedPartitions.
@Test(timeout = 60000)
public void testAcquireStreamsWhenExceedMaxCachedPartitions() throws Exception {
String streamName = testName.getMethodName() + "_0000";
DistributedLogConfiguration confLocal = new DistributedLogConfiguration();
confLocal.addConfiguration(dlConf);
confLocal.setMaxCachedPartitionsPerProxy(1);
ServerConfiguration serverConfLocal = new ServerConfiguration();
serverConfLocal.addConfiguration(serverConf);
serverConfLocal.setStreamPartitionConverterClass(DelimiterStreamPartitionConverter.class);
DistributedLogServiceImpl serviceLocal = createService(serverConfLocal, confLocal);
Stream stream = serviceLocal.getLogWriter(streamName);
// stream is cached
assertNotNull(stream);
assertEquals(1, serviceLocal.getStreamManager().numCached());
// create write ops
WriteOp op0 = createWriteOp(service, streamName, 0L);
stream.submit(op0);
WriteResponse wr0 = Await.result(op0.result());
assertEquals("Op 0 should succeed", StatusCode.SUCCESS, wr0.getHeader().getCode());
assertEquals(1, serviceLocal.getStreamManager().numAcquired());
// should fail to acquire another partition
try {
serviceLocal.getLogWriter(testName.getMethodName() + "_0001");
fail("Should fail to acquire new streams");
} catch (StreamUnavailableException sue) {
// expected
}
assertEquals(1, serviceLocal.getStreamManager().numCached());
assertEquals(1, serviceLocal.getStreamManager().numAcquired());
// should be able to acquire partitions from other streams
String anotherStreamName = testName.getMethodName() + "-another_0001";
Stream anotherStream = serviceLocal.getLogWriter(anotherStreamName);
assertNotNull(anotherStream);
assertEquals(2, serviceLocal.getStreamManager().numCached());
// create write ops
WriteOp op1 = createWriteOp(service, anotherStreamName, 0L);
anotherStream.submit(op1);
WriteResponse wr1 = Await.result(op1.result());
assertEquals("Op 1 should succeed", StatusCode.SUCCESS, wr1.getHeader().getCode());
assertEquals(2, serviceLocal.getStreamManager().numAcquired());
}
use of com.twitter.distributedlog.service.stream.Stream in project distributedlog by twitter.
the class DistributedLogServiceImpl method executeStreamOp.
private void executeStreamOp(final StreamOp op) {
// Must attach this as early as possible--returning before this point will cause us to
// lose the status code.
op.responseHeader().addEventListener(new FutureEventListener<ResponseHeader>() {
@Override
public void onSuccess(ResponseHeader header) {
if (header.getLocation() != null || header.getCode() == StatusCode.FOUND) {
redirects.inc();
}
countStatusCode(header.getCode());
}
@Override
public void onFailure(Throwable cause) {
}
});
try {
// Apply the request limiter
limiter.apply(op);
// Execute per-op pre-exec code
op.preExecute();
} catch (TooManyStreamsException e) {
// Translate to StreamUnavailableException to ensure that the client will redirect
// to a different host. Ideally we would be able to return TooManyStreamsException,
// but the way exception handling works right now we can't control the handling in
// the client because client changes deploy very slowly.
op.fail(new StreamUnavailableException(e.getMessage()));
return;
} catch (Exception e) {
op.fail(e);
return;
}
Stream stream;
try {
stream = getLogWriter(op.streamName());
} catch (RegionUnavailableException rue) {
// redirect the requests to other region
op.fail(new RegionUnavailableException("Region " + serverRegionId + " is unavailable."));
return;
} catch (IOException e) {
op.fail(e);
return;
}
if (null == stream) {
// redirect the requests when stream is unavailable.
op.fail(new ServiceUnavailableException("Server " + clientId + " is closed."));
return;
}
if (op instanceof WriteOpWithPayload) {
WriteOpWithPayload writeOp = (WriteOpWithPayload) op;
windowedBps.add(writeOp.getPayloadSize());
windowedRps.inc();
}
stream.submit(op);
}
use of com.twitter.distributedlog.service.stream.Stream in project distributedlog by twitter.
the class TestDistributedLogService method testAcquireStreamsWhenExceedMaxAcquiredPartitions.
@Test(timeout = 60000)
public void testAcquireStreamsWhenExceedMaxAcquiredPartitions() throws Exception {
String streamName = testName.getMethodName() + "_0000";
DistributedLogConfiguration confLocal = new DistributedLogConfiguration();
confLocal.addConfiguration(dlConf);
confLocal.setMaxCachedPartitionsPerProxy(-1);
confLocal.setMaxAcquiredPartitionsPerProxy(1);
ServerConfiguration serverConfLocal = new ServerConfiguration();
serverConfLocal.addConfiguration(serverConf);
serverConfLocal.setStreamPartitionConverterClass(DelimiterStreamPartitionConverter.class);
DistributedLogServiceImpl serviceLocal = createService(serverConfLocal, confLocal);
Stream stream = serviceLocal.getLogWriter(streamName);
// stream is cached
assertNotNull(stream);
assertEquals(1, serviceLocal.getStreamManager().numCached());
// create write ops
WriteOp op0 = createWriteOp(service, streamName, 0L);
stream.submit(op0);
WriteResponse wr0 = Await.result(op0.result());
assertEquals("Op 0 should succeed", StatusCode.SUCCESS, wr0.getHeader().getCode());
assertEquals(1, serviceLocal.getStreamManager().numAcquired());
// should be able to cache partitions from same stream
String anotherStreamName = testName.getMethodName() + "_0001";
Stream anotherStream = serviceLocal.getLogWriter(anotherStreamName);
assertNotNull(anotherStream);
assertEquals(2, serviceLocal.getStreamManager().numCached());
// create write ops
WriteOp op1 = createWriteOp(service, anotherStreamName, 0L);
anotherStream.submit(op1);
WriteResponse wr1 = Await.result(op1.result());
assertEquals("Op 1 should fail", StatusCode.STREAM_UNAVAILABLE, wr1.getHeader().getCode());
assertEquals(1, serviceLocal.getStreamManager().numAcquired());
}
Aggregations