示例#1
0
    public KuduSession(
        KuduClient client,
        KuduSessionOptions options,
        ILoggerFactory loggerFactory,
        long txnId)
    {
        _client  = client;
        _options = options;
        _txnId   = txnId;
        _logger  = loggerFactory.CreateLogger <KuduSession>();

        var channelOptions = new BoundedChannelOptions(options.Capacity)
        {
            SingleWriter = false,
            SingleReader = true,
            FullMode     = BoundedChannelFullMode.Wait,
            AllowSynchronousContinuations = false
        };

        var channel = Channel.CreateBounded <KuduOperation>(channelOptions);

        _writer = channel.Writer;
        _reader = channel.Reader;

        _singleFlush = new SemaphoreSlim(1, 1);
        _flushCts    = new CancellationTokenSource();
        _flushTcs    = new TaskCompletionSource(
            TaskCreationOptions.RunContinuationsAsynchronously);

        _consumeTask = ConsumeAsync();
    }
    private async Task WriteAsync(CancellationToken cancellationToken)
    {
        Exception sessionException = null;
        Exception exception;

        ValueTask HandleSessionExceptionAsync(SessionExceptionContext context)
        {
            Volatile.Write(ref sessionException, context.Exception);
            return(new ValueTask());
        }

        var options = new KuduSessionOptions
        {
            ExceptionHandler = HandleSessionExceptionAsync
        };

        await using var session = _client.NewSession(options);

        int  currentRowKey = 0;
        bool flush         = false;

        while (true)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                break;
            }

            exception = Volatile.Read(ref sessionException);
            if (exception != null)
            {
                throw exception;
            }

            var row = ClientTestUtil.CreateBasicSchemaInsert(_table, currentRowKey);
            await session.EnqueueAsync(row, CancellationToken.None);

            if (flush)
            {
                await session.FlushAsync(CancellationToken.None);
            }

            // Every 10 rows we flush and change the flush mode randomly.
            if (currentRowKey % 10 == 0)
            {
                flush = ThreadSafeRandom.Instance.NextBool();
            }

            currentRowKey++;
        }

        await session.FlushAsync(CancellationToken.None);

        exception = Volatile.Read(ref sessionException);
        if (exception != null)
        {
            throw exception;
        }
    }
示例#3
0
    public async Task TestExceptionCallback()
    {
        int numCallbacks = 0;
        SessionExceptionContext sessionContext = null;

        var builder = ClientTestUtil.GetBasicSchema()
                      .SetTableName(nameof(TestExceptionCallback));

        var table = await _client.CreateTableAsync(builder);

        var row1 = ClientTestUtil.CreateBasicSchemaInsert(table, 1);
        var row2 = ClientTestUtil.CreateBasicSchemaInsert(table, 1);

        var sessionOptions = new KuduSessionOptions
        {
            ExceptionHandler = HandleSessionExceptionAsync
        };

        await using var session = _client.NewSession(sessionOptions);

        await session.EnqueueAsync(row1);

        await session.FlushAsync();

        await session.EnqueueAsync(row2);

        await session.FlushAsync();

        ValueTask HandleSessionExceptionAsync(SessionExceptionContext context)
        {
            numCallbacks++;
            sessionContext = context;
            return(new ValueTask());
        }

        Assert.Equal(1, numCallbacks);

        var errorRow = Assert.Single(sessionContext.Rows);

        Assert.Same(row2, errorRow);

        var exception    = Assert.IsType <KuduWriteException>(sessionContext.Exception);
        var exceptionRow = Assert.Single(exception.PerRowErrors);

        Assert.True(exceptionRow.IsAlreadyPresent);
    }