Search in sources :

Example 1 with Stream

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());
}
Also used : WriteResponse(com.twitter.distributedlog.thrift.service.WriteResponse) StreamManagerImpl(com.twitter.distributedlog.service.stream.StreamManagerImpl) WriteContext(com.twitter.distributedlog.thrift.service.WriteContext) DistributedLogConfiguration(com.twitter.distributedlog.DistributedLogConfiguration) HeartbeatOptions(com.twitter.distributedlog.thrift.service.HeartbeatOptions) StreamImpl(com.twitter.distributedlog.service.stream.StreamImpl) Future(com.twitter.util.Future) Stream(com.twitter.distributedlog.service.stream.Stream) ArrayList(java.util.ArrayList) List(java.util.List) Test(org.junit.Test)

Example 2 with Stream

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());
}
Also used : StreamUnavailableException(com.twitter.distributedlog.exceptions.StreamUnavailableException) DistributedLogConfiguration(com.twitter.distributedlog.DistributedLogConfiguration) WriteOp(com.twitter.distributedlog.service.stream.WriteOp) ServerConfiguration(com.twitter.distributedlog.service.config.ServerConfiguration) WriteResponse(com.twitter.distributedlog.thrift.service.WriteResponse) Stream(com.twitter.distributedlog.service.stream.Stream) Test(org.junit.Test)

Example 3 with Stream

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);
}
Also used : StreamUnavailableException(com.twitter.distributedlog.exceptions.StreamUnavailableException) WriteOpWithPayload(com.twitter.distributedlog.service.stream.WriteOpWithPayload) ResponseHeader(com.twitter.distributedlog.thrift.service.ResponseHeader) RegionUnavailableException(com.twitter.distributedlog.exceptions.RegionUnavailableException) TooManyStreamsException(com.twitter.distributedlog.exceptions.TooManyStreamsException) Stream(com.twitter.distributedlog.service.stream.Stream) IOException(java.io.IOException) ServiceUnavailableException(com.twitter.distributedlog.exceptions.ServiceUnavailableException) ServiceUnavailableException(com.twitter.distributedlog.exceptions.ServiceUnavailableException) StreamUnavailableException(com.twitter.distributedlog.exceptions.StreamUnavailableException) RegionUnavailableException(com.twitter.distributedlog.exceptions.RegionUnavailableException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) IOException(java.io.IOException) TooManyStreamsException(com.twitter.distributedlog.exceptions.TooManyStreamsException)

Example 4 with Stream

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());
}
Also used : DistributedLogConfiguration(com.twitter.distributedlog.DistributedLogConfiguration) WriteOp(com.twitter.distributedlog.service.stream.WriteOp) ServerConfiguration(com.twitter.distributedlog.service.config.ServerConfiguration) WriteResponse(com.twitter.distributedlog.thrift.service.WriteResponse) Stream(com.twitter.distributedlog.service.stream.Stream) Test(org.junit.Test)

Aggregations

Stream (com.twitter.distributedlog.service.stream.Stream)4 DistributedLogConfiguration (com.twitter.distributedlog.DistributedLogConfiguration)3 WriteResponse (com.twitter.distributedlog.thrift.service.WriteResponse)3 Test (org.junit.Test)3 StreamUnavailableException (com.twitter.distributedlog.exceptions.StreamUnavailableException)2 ServerConfiguration (com.twitter.distributedlog.service.config.ServerConfiguration)2 WriteOp (com.twitter.distributedlog.service.stream.WriteOp)2 RegionUnavailableException (com.twitter.distributedlog.exceptions.RegionUnavailableException)1 ServiceUnavailableException (com.twitter.distributedlog.exceptions.ServiceUnavailableException)1 TooManyStreamsException (com.twitter.distributedlog.exceptions.TooManyStreamsException)1 StreamImpl (com.twitter.distributedlog.service.stream.StreamImpl)1 StreamManagerImpl (com.twitter.distributedlog.service.stream.StreamManagerImpl)1 WriteOpWithPayload (com.twitter.distributedlog.service.stream.WriteOpWithPayload)1 HeartbeatOptions (com.twitter.distributedlog.thrift.service.HeartbeatOptions)1 ResponseHeader (com.twitter.distributedlog.thrift.service.ResponseHeader)1 WriteContext (com.twitter.distributedlog.thrift.service.WriteContext)1 Future (com.twitter.util.Future)1 IOException (java.io.IOException)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1