CqlSharp.Protocol.Frame.GetFrameBytes C# (CSharp) Method

GetFrameBytes() public method

Gets the frame bytes.
public GetFrameBytes ( bool compress, int compressTreshold ) : PoolMemoryStream
compress bool
compressTreshold int
return CqlSharp.Memory.PoolMemoryStream
        public PoolMemoryStream GetFrameBytes(bool compress, int compressTreshold)
        {
            var buffer = new PoolMemoryStream();

            int versionByte = (ProtocolVersion & 0x7f) | (IsRequest ? 0 : 0x80);
            buffer.WriteByte((byte)versionByte);
            buffer.WriteByte((byte)Flags);
            if(ProtocolVersion <= 2)
                buffer.WriteByte(unchecked((byte)Stream));
            else
                buffer.WriteShort(unchecked((ushort)Stream));
            buffer.WriteByte((byte)OpCode);

            //write length placeholder
            buffer.WriteInt(0);

            long headerLength = buffer.Position;

            //write uncompressed data
            WriteData(buffer);

            //compress if allowed, and buffer is large enough to compress
            if(compress && buffer.Length > headerLength + compressTreshold)
            {
                //rewind to start of content
                buffer.Position = headerLength;

                //compress data to temporary stream
                using(var compressed = new PoolMemoryStream())
                {
                    //compress the data to the buffer
                    int length = Compressor.Compress(buffer, compressed);

                    //add compression to flags
                    Flags |= FrameFlags.Compression;
                    buffer.Position = 1;
                    buffer.WriteByte((byte)Flags);

                    //overwrite data with compressed data
                    buffer.Position = headerLength;
                    compressed.Position = 0;
                    compressed.CopyTo(buffer);
                    buffer.SetLength(headerLength + length);
                }
            }

            //overwrite length with real value
            buffer.Position = headerLength - 4;
            buffer.WriteInt((int)(buffer.Length - headerLength));

            //reset buffer position
            buffer.Position = 0;

            //return the buffer
            return buffer;
        }

Usage Example

示例#1
0
        /// <summary>
        ///   Submits a frame, and waits until response is received
        /// </summary>
        /// <param name="frame"> The frame to send. </param>
        /// <param name="logger">logger to write progress to</param>
        /// <param name="load"> the load indication of the request. Used for balancing queries over nodes and connections </param>
        /// <param name="isConnecting">indicates if this request is send as part of connection setup protocol</param>
        /// <returns> </returns>
        internal async Task<Frame> SendRequestAsync(Frame frame, Logger logger, int load = 1, bool isConnecting = false)
        {
            try
            {
                //make sure we're already connected
                if (!isConnecting)
                    await OpenAsync(logger).ConfigureAwait(false);

                //make sure we are connected
                if (!IsConnected)
                    throw new IOException("Not connected");

                //count the operation
                Interlocked.Increment(ref _activeRequests);

                //increase the load
                UpdateLoad(load, logger);

                logger.LogVerbose("Waiting for connection lock on {0}...", this);

                //wait until allowed to submit a frame
                await _frameSubmitLock.WaitAsync().ConfigureAwait(false);

                //get a task that gets completed when a response is received
                var waitTask = new TaskCompletionSource<Frame>();

                //get a stream id, and store wait task under that id
                sbyte id;
                lock (_availableQueryIds)
                {
                    id = _availableQueryIds.Dequeue();
                    _openRequests.Add(id, waitTask);
                }

                try
                {
                    //send frame
                    frame.Stream = id;

                    //serialize frame outside lock
                    Stream frameBytes = frame.GetFrameBytes(_allowCompression && !isConnecting, _cluster.Config.CompressionTreshold);

                    await _writeLock.WaitAsync().ConfigureAwait(false);
                    try
                    {
                        //final check to make sure we're connected
                        if (_connectionState != 1)
                            throw new IOException("Not connected");

                        logger.LogVerbose("Sending {0} Frame with Id {1}, to {2}", frame.OpCode, id, this);

                        await frameBytes.CopyToAsync(_writeStream).ConfigureAwait(false);
                    }
                    finally
                    {
                        _writeLock.Release();
                        frameBytes.Dispose();
                    }

                    //wait until response is received
                    Frame response = await waitTask.Task.ConfigureAwait(false);

                    logger.LogVerbose("{0} response for frame with Id {1} received from {2}", response.OpCode, id, Address);

                    //throw error if result is an error
                    var error = response as ErrorFrame;
                    if (error != null)
                    {
                        throw error.Exception;
                    }

                    //return response
                    return response;
                }
                finally
                {
                    //return request slot to the pool
                    lock (_availableQueryIds)
                    {
                        _openRequests.Remove(id);
                        _availableQueryIds.Enqueue(id);
                    }

                    //allow another frame to be send
                    _frameSubmitLock.Release();

                    //reduce load, we are done
                    Interlocked.Decrement(ref _activeRequests);
                    UpdateLoad(-load, logger);
                }
            }
            catch (ProtocolException pex)
            {
                switch (pex.Code)
                {
                    case ErrorCode.IsBootstrapping:
                    case ErrorCode.Overloaded:

                        using (logger.ThreadBinding())
                        {
                            //IO or node status related error, dispose this connection
                            Dispose(true, pex);
                            throw;
                        }

                    default:
                        //some other Cql error (syntax ok?), simply rethrow
                        throw;
                }
            }
            catch (Exception ex)
            {
                using (logger.ThreadBinding())
                {
                    //connection collapsed, dispose this connection
                    Dispose(true, ex);
                    throw;
                }
            }
        }
All Usage Examples Of CqlSharp.Protocol.Frame::GetFrameBytes