protected internal override void ParseResult(Connection conn) { // Read header. conn.ReadFully(dataBuffer, MSG_TOTAL_HEADER_SIZE); conn.UpdateLastUsed(); int resultCode = dataBuffer[13]; if (resultCode == 0) { exists = true; return; } if (resultCode == ResultCode.KEY_NOT_FOUND_ERROR) { exists = false; return; } if (resultCode == ResultCode.FILTERED_OUT) { if (policy.failOnFilteredOut) { throw new AerospikeException(resultCode); } exists = true; return; } throw new AerospikeException(resultCode); }
private void ExecuteCommand(Cluster cluster, AdminPolicy policy) { WriteSize(); Node node = cluster.GetRandomNode(); int timeout = (policy == null) ? 1000 : policy.timeout; Connection conn = node.GetConnection(timeout); try { conn.Write(dataBuffer, dataOffset); conn.ReadFully(dataBuffer, HEADER_SIZE); conn.UpdateLastUsed(); node.PutConnection(conn); } catch (Exception) { // Garbage may be in socket. Do not put back into pool. node.CloseConnectionOnError(conn); throw; } int result = dataBuffer[RESULT_CODE]; if (result != 0) { throw new AerospikeException(result); } }
protected internal override void ParseResult(Connection conn) { // Read header. conn.ReadFully(dataBuffer, MSG_TOTAL_HEADER_SIZE); conn.UpdateLastUsed(); int resultCode = dataBuffer[13]; if (resultCode == 0) { int generation = ByteUtil.BytesToInt(dataBuffer, 14); int expiration = ByteUtil.BytesToInt(dataBuffer, 18); record = new Record(null, generation, expiration); return; } if (resultCode == ResultCode.KEY_NOT_FOUND_ERROR) { return; } if (resultCode == ResultCode.FILTERED_OUT) { if (policy.failOnFilteredOut) { throw new AerospikeException(resultCode); } return; } throw new AerospikeException(resultCode); }
//------------------------------------------------------- // Private methods. //------------------------------------------------------- /// <summary> /// Issue request and set results buffer. This method is used internally. /// The static request methods should be used instead. /// </summary> /// <param name="conn">socket connection to server node</param> /// <exception cref="AerospikeException">if socket send or receive fails</exception> private void SendCommand(Connection conn) { try { // Write size field. ulong size = ((ulong)offset - 8L) | (2L << 56) | (1L << 48); ByteUtil.LongToBytes(size, buffer, 0); // Write. conn.Write(buffer, offset); // Read - reuse input buffer. conn.ReadFully(buffer, 8); size = (ulong)ByteUtil.BytesToLong(buffer, 0); length = (int)(size & 0xFFFFFFFFFFFFL); ResizeBuffer(length); conn.ReadFully(buffer, length); conn.UpdateLastUsed(); offset = 0; } catch (SocketException se) { throw new AerospikeException(se); } }
/// <summary> /// Put connection back into connection pool. /// </summary> /// <param name="conn">socket connection</param> public void PutConnection(Connection conn) { conn.UpdateLastUsed(); if (!active || !conn.pool.queue.TryAdd(conn)) { CloseConnection(conn); } }
/// <summary> /// Put connection back into connection pool. /// </summary> /// <param name="conn">socket connection</param> public void PutConnection(Connection conn) { conn.UpdateLastUsed(); if (active) { conn.pool.Enqueue(conn); } else { CloseConnection(conn); } }
private int ReadBlocks(Connection conn) { int status = 0; while (status == 0) { conn.ReadFully(dataBuffer, 8); long size = ByteUtil.BytesToLong(dataBuffer, 0); int receiveSize = ((int)(size & 0xFFFFFFFFFFFFL)); if (receiveSize > 0) { if (receiveSize > dataBuffer.Length) { dataBuffer = ThreadLocalData.ResizeBuffer(receiveSize); } conn.ReadFully(dataBuffer, receiveSize); conn.UpdateLastUsed(); status = ParseBlock(receiveSize); } } return(status); }
protected internal override void ParseResult(Connection conn) { // Read header. conn.ReadFully(dataBuffer, 8); long sz = ByteUtil.BytesToLong(dataBuffer, 0); int receiveSize = (int)(sz & 0xFFFFFFFFFFFFL); if (receiveSize <= 0) { throw new AerospikeException("Invalid receive size: " + receiveSize); } SizeBuffer(receiveSize); conn.ReadFully(dataBuffer, receiveSize); conn.UpdateLastUsed(); ulong type = (ulong)((sz >> 48) & 0xff); if (type == Command.AS_MSG_TYPE) { dataOffset = 5; } else if (type == Command.MSG_TYPE_COMPRESSED) { int usize = (int)ByteUtil.BytesToLong(dataBuffer, 0); byte[] ubuf = new byte[usize]; ByteUtil.Decompress(dataBuffer, 8, receiveSize, ubuf, usize); dataBuffer = ubuf; dataOffset = 13; } else { throw new AerospikeException("Invalid proto type: " + type + " Expected: " + Command.AS_MSG_TYPE); } int resultCode = dataBuffer[dataOffset]; dataOffset++; int generation = ByteUtil.BytesToInt(dataBuffer, dataOffset); dataOffset += 4; int expiration = ByteUtil.BytesToInt(dataBuffer, dataOffset); dataOffset += 8; int fieldCount = ByteUtil.BytesToShort(dataBuffer, dataOffset); dataOffset += 2; int opCount = ByteUtil.BytesToShort(dataBuffer, dataOffset); dataOffset += 2; if (resultCode == 0) { if (opCount == 0) { // Bin data was not returned. record = new Record(null, generation, expiration); return; } record = ParseRecord(opCount, fieldCount, generation, expiration); return; } if (resultCode == ResultCode.KEY_NOT_FOUND_ERROR) { HandleNotFound(resultCode); return; } if (resultCode == ResultCode.FILTERED_OUT) { if (policy.failOnFilteredOut) { throw new AerospikeException(resultCode); } return; } if (resultCode == ResultCode.UDF_BAD_RESPONSE) { record = ParseRecord(opCount, fieldCount, generation, expiration); HandleUdfError(resultCode); return; } throw new AerospikeException(resultCode); }
public void Execute() { Policy policy = GetPolicy(); int remainingMillis = policy.timeout; DateTime limit = DateTime.UtcNow.AddMilliseconds(remainingMillis); Node node = null; Exception exception = null; int failedNodes = 0; int failedConns = 0; int iterations = 0; dataBuffer = ThreadLocalData.GetBuffer(); // Execute command until successful, timed out or maximum iterations have been reached. while (true) { try { node = GetNode(); Connection conn = node.GetConnection(remainingMillis); try { // Set command buffer. WriteBuffer(); // Reset timeout in send buffer (destined for server) and socket. ByteUtil.IntToBytes((uint)remainingMillis, dataBuffer, 22); // Send command. conn.Write(dataBuffer, dataOffset); // Parse results. ParseResult(conn); // Reflect healthy status. conn.UpdateLastUsed(); // Put connection back in pool. node.PutConnection(conn); // Command has completed successfully. Exit method. return; } catch (AerospikeException ae) { if (ae.KeepConnection()) { // Put connection back in pool. conn.UpdateLastUsed(); node.PutConnection(conn); } else { // Close socket to flush out possible garbage. Do not put back in pool. node.CloseConnection(conn); } throw; } catch (SocketException ioe) { node.CloseConnection(conn); if (ioe.ErrorCode == (int)SocketError.TimedOut) { // Full timeout has been reached. Do not retry. // Close socket to flush out possible garbage. Do not put back in pool. throw new AerospikeException.Timeout(node, policy.timeout, ++iterations, failedNodes, failedConns); } else { // IO errors are considered temporary anomalies. Retry. // Close socket to flush out possible garbage. Do not put back in pool. exception = ioe; } } catch (Exception) { // All runtime exceptions are considered fatal. Do not retry. // Close socket to flush out possible garbage. Do not put back in pool. node.CloseConnection(conn); throw; } } catch (AerospikeException.InvalidNode ine) { // Node is currently inactive. Retry. exception = ine; failedNodes++; } catch (AerospikeException.Connection ce) { // Socket connection error has occurred. Retry. exception = ce; failedConns++; } if (++iterations > policy.maxRetries) { break; } // Check for client timeout. if (policy.timeout > 0) { remainingMillis = (int)limit.Subtract(DateTime.UtcNow).TotalMilliseconds - policy.sleepBetweenRetries; if (remainingMillis <= 0) { break; } } if (policy.sleepBetweenRetries > 0) { // Sleep before trying again. Util.Sleep(policy.sleepBetweenRetries); } // Reset node reference and try again. node = null; } // Retries have been exhausted. Throw last exception. throw exception; }
protected internal sealed override void ParseResult(Connection conn) { // Read blocks of records. Do not use thread local receive buffer because each // block will likely be too big for a cache. Also, scan callbacks can nest // further database commands which would contend with the thread local receive buffer. // Instead, use separate heap allocated buffers. byte[] protoBuf = new byte[8]; byte[] buf = null; byte[] ubuf = null; int receiveSize; while (true) { // Read header conn.ReadFully(protoBuf, 8); long proto = ByteUtil.BytesToLong(protoBuf, 0); int size = (int)(proto & 0xFFFFFFFFFFFFL); if (size <= 0) { continue; } // Prepare buffer if (buf == null || size > buf.Length) { // Corrupted data streams can result in a huge length. // Do a sanity check here. if (size > MAX_BUFFER_SIZE) { throw new AerospikeException("Invalid proto size: " + size); } int capacity = (size + 16383) & ~16383; // Round up in 16KB increments. buf = new byte[capacity]; } // Read remaining message bytes in group. conn.ReadFully(buf, size); conn.UpdateLastUsed(); ulong type = (ulong)((proto >> 48) & 0xff); if (type == Command.AS_MSG_TYPE) { dataBuffer = buf; dataOffset = 0; receiveSize = size; } else if (type == Command.MSG_TYPE_COMPRESSED) { int usize = (int)ByteUtil.BytesToLong(buf, 0); if (ubuf == null || usize > ubuf.Length) { if (usize > MAX_BUFFER_SIZE) { throw new AerospikeException("Invalid proto size: " + usize); } int capacity = (usize + 16383) & ~16383; // Round up in 16KB increments. ubuf = new byte[capacity]; } ByteUtil.Decompress(buf, 8, size, ubuf, usize); dataBuffer = ubuf; dataOffset = 8; receiveSize = usize; } else { throw new AerospikeException("Invalid proto type: " + type + " Expected: " + Command.AS_MSG_TYPE); } if (!ParseGroup(receiveSize)) { break; } } }
/// <summary> /// Put connection back into connection pool. /// </summary> /// <param name="conn">socket connection</param> public void PutConnection(Connection conn) { conn.UpdateLastUsed(); if (!active || !connectionQueue.TryAdd(conn)) { CloseConnection(conn); } }