public void Send(MemcachedCommand command) { Thread.MemoryBarrier(); InitiateCommand(command); _writeAsync.BeginAsync(_stream); }
private MemcachedCommand GetNextCommandAfterPreviousSendCompleted(MemcachedCommand command) { lock (_gate) { _pendingSends.Dequeue(); if (_isWriterConnectionOpen && _isReaderConnectionOpen && !_hasBeenDisposed && _pendingSends.Count > 0) { var commandBeingSent = _pendingSends.Peek(); _pendingReceives[commandBeingSent.Id] = commandBeingSent; return commandBeingSent; } return null; } }
private void WriteCommandHeader(MemcachedCommand command) { command.BeginWriting(); WriteRequestHeader(_sendBuffer, command.Opcode, command.RequestHeader); const int requestHeaderSize = 24; _currentByteInSendBuffer += requestHeaderSize; command.WriteExtras(new ArraySegment<byte>(_sendBuffer, _currentByteInSendBuffer, command.RequestHeader.ExtrasLength)); _currentByteInSendBuffer += command.RequestHeader.ExtrasLength; command.WriteKey(new ArraySegment<byte>(_sendBuffer, _currentByteInSendBuffer, command.RequestHeader.KeyLength)); _currentByteInSendBuffer += command.RequestHeader.KeyLength; }
public WriteState(MemcachedCommand command) { Command = command; TotalBytesInValue = command.RequestHeader.TotalBodyLength - command.RequestHeader.KeyLength - command.RequestHeader.ExtrasLength; CurrentByteInValue = 0; }
public bool TrySend(MemcachedCommand command) { bool isWriterIdle = false; lock (_gate) { if (_hasBeenDisposed) return false; var areEitherReaderOrWriterClosed = !_isReaderConnectionOpen || !_isWriterConnectionOpen; if (areEitherReaderOrWriterClosed || _hasBeenDisposed) { return false; } _pendingSends.Enqueue(command); isWriterIdle = _pendingSends.Count == 1; if (isWriterIdle) { _pendingReceives[command.Id] = command; } } if (isWriterIdle) { _requestWriter.Send(command); } return true; }
private void RemoveFromPendingReceives(MemcachedCommand command) { lock (_gate) { _pendingReceives.Remove(command.Id); } }
private void OnErrorReceived(MemcachedCommand command) { RemoveFromPendingReceives(command); switch (command.ResponseStatus) { case ResponseStatus.VbucketBelongsToAnotherServer: case ResponseStatus.Busy: case ResponseStatus.TemporaryFailure: { var ev = OnRecoverableError; if (ev != null) { ev(this.ServerId, command); } } break; case ResponseStatus.NoError: throw new Exception("Should be impossible to get here..."); default: //The error is not something we can deal with inside the library itself, either the caller screwed up, or there was a catastrophic failure. command.NotifyComplete(); break; } }
private void SendCommandWithVBucketId(MemcachedCommand command) { Cluster cluster = _cluster; command.SetVBucketId(cluster.GetVBucket(command.Key)); SendCommand(cluster, command); }
private static void SendByLinearlyPollingServers(Cluster cluster, string lastServerTriedToSendToId, MemcachedCommand command) { int indexOfServerToTry = GetIndexOfNextServerInCluster(cluster, lastServerTriedToSendToId); for (int i = 0; i < cluster.Servers.Count; i++) { if (cluster.Servers[indexOfServerToTry].TrySend(command)) { return; } indexOfServerToTry = MathUtils.CircularIncrement(indexOfServerToTry, cluster.Servers.Count); } command.NotifyComplete(ResponseStatus.DisconnectionOccuredWhileOperationWaitingToBeSent); }
private void OnWrongVBucketForServer(string lastServerTriedToSendToId, MemcachedCommand command) { Cluster cluster = _cluster; var fastForwardedServers = cluster.GetFastForwardedServersForVBucket(command.VBucketId); if (fastForwardedServers == null || !TrySendCommand(fastForwardedServers, command)) { SendByLinearlyPollingServers(cluster, lastServerTriedToSendToId, command); return; } }
private void OnPossiblyRecoverableMemcachedError(string serverid, MemcachedCommand command) { var cluster = _cluster; switch (command.ResponseStatus) { case ResponseStatus.VbucketBelongsToAnotherServer: OnWrongVBucketForServer(serverid, command); break; case ResponseStatus.Busy: case ResponseStatus.TemporaryFailure: SendCommand(cluster, command); //Retry break; default: throw new Exception("Should be impossible to get here..."); } }
private static bool TrySendCommand(List<Server> serversForVbucket, MemcachedCommand command) { for (int iServer = 0; iServer < serversForVbucket.Count; iServer++) { if (serversForVbucket[iServer].TrySend(command)) { return true; } } return false; }
private static bool TrySendCommand(Cluster cluster, MemcachedCommand command) { var serversForVbucket = cluster.GetServersForVBucket(command.VBucketId); return TrySendCommand(serversForVbucket, command); }
private static void SendCommand(Cluster cluster, MemcachedCommand command) { if (!TrySendCommand(cluster, command)) { command.NotifyComplete(ResponseStatus.DisconnectionOccuredWhileOperationWaitingToBeSent); } }
private void InitiateCommand(MemcachedCommand command) { WriteCommandHeader(command); _writeState = new WriteState(command); }
private void OnCommandResponseReceived(MemcachedCommand command) { RemoveFromPendingReceives(command); command.NotifyComplete(); }
public bool TrySend(MemcachedCommand command) { return this.MemcachedClient.TrySend(command); }