private void Bench_LoopOrAsyncReceive(DisqueCommand command) { // ここで、コマンドの結果内容を精査する場合、結果を生成する必要があるが、どうするかな、、 var result = new DisquuunResult[0]; socketToken.continuation = socketToken.AsyncCallback(command, result); if (socketToken.continuation) { System.Threading.Tasks.Task.Run(() => { Bench_LoopOrAsyncReceive(command); }); } else { socketToken.socketState = SocketState.OPENED; SocketReloaded(this); } }
public static ScanResult ScanBuffer(DisqueCommand command, byte[] sourceBuffer, long length, string socketId) { var cursor = 0; switch (command) { case DisqueCommand.ADDJOB: { switch (sourceBuffer[cursor]) { // case ByteError: { // - // var lineEndCursor = ReadLine(sourceBuffer, cursor); // cursor = cursor + 1;// add header byte size = 1. // if (Failed != null) { // var errorStr = Encoding.UTF8.GetString(sourceBuffer, cursor, lineEndCursor - cursor); // // Disquuun.Log("errorStr:" + errorStr); // Failed(currentCommand, errorStr); // } // cursor = lineEndCursor + 2;// CR + LF // break; // } case ByteStatus: { // + count var lineEndCursor = ReadLine(sourceBuffer, cursor, length); if (lineEndCursor == -1) { return(new ScanResult(false)); } cursor = cursor + 1; // add header byte size = 1. var countBuffer = new ArraySegment <byte>(sourceBuffer, cursor, lineEndCursor - cursor); cursor = lineEndCursor + 2; // CR + LF return(new ScanResult(cursor, new DisquuunResult[] { new DisquuunResult(countBuffer) })); } } break; } case DisqueCommand.GETJOB: { switch (sourceBuffer[cursor]) { case ByteMultiBulk: { DisquuunResult[] jobDatas = null; { // * count. var lineEndCursor = ReadLine(sourceBuffer, cursor, length); if (lineEndCursor == -1) { return(new ScanResult(false)); } cursor = cursor + 1; // add header byte size = 1. var bulkCountStr = Encoding.UTF8.GetString(sourceBuffer, cursor, lineEndCursor - cursor); // TestLogger.Log("bulkCountStr:" + bulkCountStr); var bulkCountNum = Convert.ToInt32(bulkCountStr); cursor = lineEndCursor + 2; // CR + LF // trigger when GETJOB NOHANG if (bulkCountNum < 0) { return(new ScanResult(cursor, new DisquuunResult[] {})); } jobDatas = new DisquuunResult[bulkCountNum]; for (var i = 0; i < bulkCountNum; i++) { var itemCount = 0; { // * count. var lineEndCursor2 = ReadLine(sourceBuffer, cursor, length); if (lineEndCursor2 == -1) { return(new ScanResult(false)); } cursor = cursor + 1; // add header byte size = 1. var bulkCountStr2 = Encoding.UTF8.GetString(sourceBuffer, cursor, lineEndCursor2 - cursor); itemCount = Convert.ToInt32(bulkCountStr2); // Disquuun.Log("itemCount:" + itemCount); cursor = lineEndCursor2 + 2; // CR + LF } // queueName { // $ count. var lineEndCursor3 = ReadLine(sourceBuffer, cursor, length); if (lineEndCursor3 == -1) { return(new ScanResult(false)); } cursor = cursor + 1; // add header byte size = 1 var countStr = Encoding.UTF8.GetString(sourceBuffer, cursor, lineEndCursor3 - cursor); var strNum = Convert.ToInt32(countStr); cursor = lineEndCursor3 + 2; // CR + LF // $ bulk. if (ShortageOfReadableLength(sourceBuffer, cursor, strNum)) { return(new ScanResult(false)); } // var nameStr = Encoding.UTF8.GetString(sourceBuffer, cursor, strNum); // Disquuun.Log("nameStr:" + nameStr); cursor = cursor + strNum + 2; // CR + LF } // jobId ArraySegment <byte> jobIdBytes; { // $ count. var lineEndCursor3 = ReadLine(sourceBuffer, cursor, length); if (lineEndCursor3 == -1) { return(new ScanResult(false)); } cursor = cursor + 1; // add header byte size = 1. var countStr = Encoding.UTF8.GetString(sourceBuffer, cursor, lineEndCursor3 - cursor); var strNum = Convert.ToInt32(countStr); // Disquuun.Log("id strNum:" + strNum); cursor = lineEndCursor3 + 2; // CR + LF // $ bulk. if (ShortageOfReadableLength(sourceBuffer, cursor, strNum)) { return(new ScanResult(false)); } jobIdBytes = new ArraySegment <byte>(sourceBuffer, cursor, strNum); // var jobIdStr = Encoding.UTF8.GetString(jobIdBytes); // Disquuun.Log("jobIdStr:" + jobIdStr); cursor = cursor + strNum + 2; // CR + LF } // jobData ArraySegment <byte> dataBytes; { // $ count. var lineEndCursor3 = ReadLine(sourceBuffer, cursor, length); if (lineEndCursor3 == -1) { return(new ScanResult(false)); } cursor = cursor + 1; // add header byte size = 1. var countStr = Encoding.UTF8.GetString(sourceBuffer, cursor, lineEndCursor3 - cursor); var strNum = Convert.ToInt32(countStr); cursor = lineEndCursor3 + 2; // CR + LF // $ bulk. if (ShortageOfReadableLength(sourceBuffer, cursor, strNum)) { return(new ScanResult(false)); } dataBytes = new ArraySegment <byte>(sourceBuffer, cursor, strNum); cursor = cursor + strNum + 2; // CR + LF } // no withcounters response. if (itemCount == 3) { jobDatas[i] = new DisquuunResult(jobIdBytes, dataBytes); // cursor = cursor + 2;// CR + LF continue; } // withcounters response. if (itemCount == 7) { ArraySegment <byte> nackCountBytes; { // $ var lineEndCursor3 = ReadLine(sourceBuffer, cursor, length); if (lineEndCursor3 == -1) { return(new ScanResult(false)); } cursor = cursor + 1; // add header byte size = 1. var countStr = Encoding.UTF8.GetString(sourceBuffer, cursor, lineEndCursor3 - cursor); var strNum = Convert.ToInt32(countStr); // Disquuun.Log("data strNum:" + strNum); cursor = lineEndCursor3 + 2; // CR + LF // ignore params. cursor = cursor + strNum + 2; // CR + LF // : var lineEndCursor4 = ReadLine(sourceBuffer, cursor, length); if (lineEndCursor4 == -1) { return(new ScanResult(false)); } cursor = cursor + 1; // add header byte size = 1. nackCountBytes = new ArraySegment <byte>(sourceBuffer, cursor, lineEndCursor4 - cursor); cursor = lineEndCursor4 + 2; // CR + LF } ArraySegment <byte> additionalDeliveriesCountBytes; { // $ var lineEndCursor3 = ReadLine(sourceBuffer, cursor, length); if (lineEndCursor3 == -1) { return(new ScanResult(false)); } cursor = cursor + 1; // add header byte size = 1. var countStr = Encoding.UTF8.GetString(sourceBuffer, cursor, lineEndCursor3 - cursor); var strNum = Convert.ToInt32(countStr); // Disquuun.Log("data strNum:" + strNum); cursor = lineEndCursor3 + 2; // CR + LF // ignore params. cursor = cursor + strNum + 2; // CR + LF // : var lineEndCursor4 = ReadLine(sourceBuffer, cursor, length); if (lineEndCursor4 == -1) { return(new ScanResult(false)); } cursor = cursor + 1; // add header byte size = 1. additionalDeliveriesCountBytes = new ArraySegment <byte>(sourceBuffer, cursor, lineEndCursor4 - cursor); jobDatas[i] = new DisquuunResult(jobIdBytes, dataBytes, nackCountBytes, additionalDeliveriesCountBytes); cursor = lineEndCursor4 + 2; // CR + LF } } } } if (jobDatas != null && 0 < jobDatas.Length) { return(new ScanResult(cursor, jobDatas)); } break; } // case ByteError: { // // - // Disquuun.Log("-"); // throw new Exception("GetJob error."); // // var lineEndCursor = ReadLine2(sourceBuffer, cursor, length); // // cursor = cursor + 1;// add header byte size = 1. // // if (Failed != null) { // // var errorStr = Encoding.UTF8.GetString(sourceBuffer, cursor, lineEndCursor - cursor); // // // Disquuun.Log("errorStr:" + errorStr); // // Failed(currentCommand, errorStr); // // } // // cursor = lineEndCursor + 2;// CR + LF // break; // } } break; } case DisqueCommand.ACKJOB: case DisqueCommand.FASTACK: { switch (sourceBuffer[cursor]) { case ByteInt: { // : count. var lineEndCursor = ReadLine(sourceBuffer, cursor, length); if (lineEndCursor == -1) { return(new ScanResult(false)); } cursor = cursor + 1; // add header byte size = 1. // var countStr = Encoding.UTF8.GetString(sourceBuffer, cursor, lineEndCursor - cursor); // Disquuun.Log("countStr:" + countStr); var countBuffer = new ArraySegment <byte>(sourceBuffer, cursor, lineEndCursor - cursor); var byteData = new DisquuunResult(countBuffer); cursor = lineEndCursor + 2; // CR + LF return(new ScanResult(cursor, new DisquuunResult[] { byteData })); } // case ByteError: { // // - // var lineEndCursor = ReadLine(sourceBuffer, cursor); // cursor = cursor + 1;// add header byte size = 1. // if (Failed != null) { // var errorStr = Encoding.UTF8.GetString(sourceBuffer, cursor, lineEndCursor - cursor); // // Disquuun.Log("errorStr:" + errorStr); // Failed(currentCommand, errorStr); // } // cursor = lineEndCursor + 2;// CR + LF // break; // } } break; } case DisqueCommand.INFO: { switch (sourceBuffer[cursor]) { case ByteBulk: { var countNum = 0; { // readbulk count. // $ var lineEndCursor = ReadLine(sourceBuffer, cursor, length); if (lineEndCursor == -1) { return(new ScanResult(false)); } cursor = cursor + 1; // add header byte size = 1. var countStr = Encoding.UTF8.GetString(sourceBuffer, cursor, lineEndCursor - cursor); countNum = Convert.ToInt32(countStr); cursor = lineEndCursor + 2; // CR + LF } { // readbulk string. if (ShortageOfReadableLength(sourceBuffer, cursor, countNum)) { return(new ScanResult(false)); } var newBuffer = new ArraySegment <byte>(sourceBuffer, cursor, countNum); cursor = cursor + countNum + 2; // CR + LF return(new ScanResult(cursor, new DisquuunResult[] { new DisquuunResult(newBuffer) })); } } } break; } case DisqueCommand.HELLO: { switch (sourceBuffer[cursor]) { case ByteMultiBulk: { ArraySegment <byte> version; ArraySegment <byte> thisNodeId; List <ArraySegment <byte> > nodeIdsAndInfos = new List <ArraySegment <byte> >(); /* * :*3 * :1 version [0][0] * * $40 this node ID [0][1] * 002698920b158ba29ff8d41d3e5303ceaf0e8d45 * * 4 [1~n][0~3] * $40 * 002698920b158ba29ff8d41d3e5303ceaf0e8d45 * * $0 * "" * * $4 * 7711 * * $1 * 1 */ { // * var lineEndCursor = ReadLine(sourceBuffer, cursor, length); if (lineEndCursor == -1) { return(new ScanResult(false)); } cursor = cursor + 1; // add header byte size = 1. // var bulkCountStr = Encoding.UTF8.GetString(sourceBuffer, cursor, lineEndCursor - cursor); // Disquuun.Log("bulkCountStr:" + bulkCountStr); cursor = lineEndCursor + 2; // CR + LF } { // : format version var lineEndCursor = ReadLine(sourceBuffer, cursor, length); if (lineEndCursor == -1) { return(new ScanResult(false)); } cursor = cursor + 1; // add header byte size = 1. version = new ArraySegment <byte>(sourceBuffer, cursor, lineEndCursor - cursor); // Disquuun.Log(":version:" + version); cursor = lineEndCursor + 2; // CR + LF } { // $ this node id var lineEndCursor = ReadLine(sourceBuffer, cursor, length); if (lineEndCursor == -1) { return(new ScanResult(false)); } cursor = cursor + 1; // add header byte size = 1. var countStr = Encoding.UTF8.GetString(sourceBuffer, cursor, lineEndCursor - cursor); var strNum = Convert.ToInt32(countStr); // Disquuun.Log("id strNum:" + strNum); cursor = lineEndCursor + 2; // CR + LF if (ShortageOfReadableLength(sourceBuffer, cursor, strNum)) { return(new ScanResult(false)); } thisNodeId = new ArraySegment <byte>(sourceBuffer, cursor, strNum); // Disquuun.Log("thisNodeId:" + thisNodeId); cursor = cursor + strNum + 2; // CR + LF } { // * node ids var lineEndCursor = ReadLine(sourceBuffer, cursor, length); cursor = cursor + 1; // add header byte size = 1. var bulkCountStr = Encoding.UTF8.GetString(sourceBuffer, cursor, lineEndCursor - cursor); var bulkCountNum = Convert.ToInt32(bulkCountStr); // Disquuun.Log("bulkCountNum:" + bulkCountNum); cursor = lineEndCursor + 2; // CR + LF // nodeId, ip, port, priority. for (var i = 0; i < bulkCountNum / 4; i++) { ArraySegment <byte> idStr; // $ nodeId { var lineEndCursor2 = ReadLine(sourceBuffer, cursor, length); if (lineEndCursor2 == -1) { return(new ScanResult(false)); } cursor = cursor + 1; // add header byte size = 1. var countStr = Encoding.UTF8.GetString(sourceBuffer, cursor, lineEndCursor2 - cursor); var strNum = Convert.ToInt32(countStr); cursor = lineEndCursor2 + 2; // CR + LF if (ShortageOfReadableLength(sourceBuffer, cursor, strNum)) { return(new ScanResult(false)); } idStr = new ArraySegment <byte>(sourceBuffer, cursor, strNum); nodeIdsAndInfos.Add(idStr); cursor = cursor + strNum + 2; // CR + LF } { var lineEndCursor2 = ReadLine(sourceBuffer, cursor, length); if (lineEndCursor2 == -1) { return(new ScanResult(false)); } cursor = cursor + 1; // add header byte size = 1. var countStr = Encoding.UTF8.GetString(sourceBuffer, cursor, lineEndCursor2 - cursor); var strNum = Convert.ToInt32(countStr); cursor = lineEndCursor2 + 2; // CR + LF if (ShortageOfReadableLength(sourceBuffer, cursor, strNum)) { return(new ScanResult(false)); } var ipStr = new ArraySegment <byte>(sourceBuffer, cursor, strNum); nodeIdsAndInfos.Add(ipStr); cursor = cursor + strNum + 2; // CR + LF } { var lineEndCursor2 = ReadLine(sourceBuffer, cursor, length); if (lineEndCursor2 == -1) { return(new ScanResult(false)); } cursor = cursor + 1; // add header byte size = 1. var countStr = Encoding.UTF8.GetString(sourceBuffer, cursor, lineEndCursor2 - cursor); var strNum = Convert.ToInt32(countStr); cursor = lineEndCursor2 + 2; // CR + LF if (ShortageOfReadableLength(sourceBuffer, cursor, strNum)) { return(new ScanResult(false)); } var portStr = new ArraySegment <byte>(sourceBuffer, cursor, strNum); nodeIdsAndInfos.Add(portStr); cursor = cursor + strNum + 2; // CR + LF } { var lineEndCursor2 = ReadLine(sourceBuffer, cursor, length); if (lineEndCursor2 == -1) { return(new ScanResult(false)); } cursor = cursor + 1; // add header byte size = 1. var countStr = Encoding.UTF8.GetString(sourceBuffer, cursor, lineEndCursor2 - cursor); var strNum = Convert.ToInt32(countStr); cursor = lineEndCursor2 + 2; // CR + LF if (ShortageOfReadableLength(sourceBuffer, cursor, strNum)) { return(new ScanResult(false)); } var priorityStr = new ArraySegment <byte>(sourceBuffer, cursor, strNum); nodeIdsAndInfos.Add(priorityStr); cursor = cursor + strNum + 2; // CR + LF } } } var byteDatas = new DisquuunResult[1 + nodeIdsAndInfos.Count / 4]; byteDatas[0] = new DisquuunResult(version, thisNodeId); for (var index = 0; index < nodeIdsAndInfos.Count / 4; index++) { var nodeId = nodeIdsAndInfos[index * 4 + 0]; var ip = nodeIdsAndInfos[index * 4 + 1]; var port = nodeIdsAndInfos[index * 4 + 2]; var priority = nodeIdsAndInfos[index * 4 + 3]; byteDatas[index + 1] = new DisquuunResult(nodeId, ip, port, priority); } return(new ScanResult(cursor, byteDatas)); } } break; } case DisqueCommand.QLEN: { switch (sourceBuffer[cursor]) { case ByteInt: { // : format version var lineEndCursor = ReadLine(sourceBuffer, cursor, length); if (lineEndCursor == -1) { return(new ScanResult(false)); } cursor = cursor + 1; // add header byte size = 1. var countBuffer = new ArraySegment <byte>(sourceBuffer, cursor, lineEndCursor - cursor); var byteData = new DisquuunResult(countBuffer); cursor = lineEndCursor + 2; // CR + LF return(new ScanResult(cursor, new DisquuunResult[] { byteData })); } } break; } case DisqueCommand.QSTAT: { // * count of item. var bulkCountNum = 0; { var lineEndCursor = ReadLine(sourceBuffer, cursor, length); if (lineEndCursor == -1) { return(new ScanResult(false)); } cursor = cursor + 1; // add header byte size = 1. var bulkCountStr = Encoding.UTF8.GetString(sourceBuffer, cursor, lineEndCursor - cursor); bulkCountNum = Convert.ToInt32(bulkCountStr); cursor = lineEndCursor + 2; // CR + LF } // items are key & value pair(maybe "import-from" will not match..) var itemCount = bulkCountNum / 2; var results = new DisquuunResult[itemCount]; for (var i = 0; i < itemCount; i++) { ArraySegment <byte> keyBytes; { // key ($) var lineEndCursor2 = ReadLine(sourceBuffer, cursor, length); if (lineEndCursor2 == -1) { return(new ScanResult(false)); } cursor = cursor + 1; // add header byte size = 1. var countStr = Encoding.UTF8.GetString(sourceBuffer, cursor, lineEndCursor2 - cursor); var strNum = Convert.ToInt32(countStr); cursor = lineEndCursor2 + 2; // CR + LF if (ShortageOfReadableLength(sourceBuffer, cursor, strNum)) { return(new ScanResult(false)); } keyBytes = new ArraySegment <byte>(sourceBuffer, cursor, strNum); cursor = cursor + strNum + 2; // CR + LF } { // value ($ or * or :) ArraySegment <byte> valBytes; var type = sourceBuffer[cursor]; /* * check next parameter = value parameter's type. * $ or * or : is expected. */ switch (type) { case ByteBulk: { // $ have string value. var lineEndCursor3 = ReadLine(sourceBuffer, cursor, length); if (lineEndCursor3 == -1) { return(new ScanResult(false)); } cursor = cursor + 1; // add header byte size = 1. var countStr = Encoding.UTF8.GetString(sourceBuffer, cursor, lineEndCursor3 - cursor); var strNum = Convert.ToInt32(countStr); cursor = lineEndCursor3 + 2; // CR + LF if (ShortageOfReadableLength(sourceBuffer, cursor, strNum)) { return(new ScanResult(false)); } valBytes = new ArraySegment <byte>(sourceBuffer, cursor, strNum); cursor = cursor + strNum + 2; // CR + LF break; } case ByteMultiBulk: case ByteInt: { // * or : have number value. var lineEndCursor3 = ReadLine(sourceBuffer, cursor, length); if (lineEndCursor3 == -1) { return(new ScanResult(false)); } cursor = cursor + 1; // add header byte size = 1. var countStr = Encoding.UTF8.GetString(sourceBuffer, cursor, lineEndCursor3 - cursor); var strNum = countStr.Length; valBytes = new ArraySegment <byte>(sourceBuffer, cursor, strNum); cursor = lineEndCursor3 + 2; // CR + LF break; } default: { throw new Exception("qstat unexpected type:" + type); } } results[i] = new DisquuunResult(keyBytes, valBytes); } } return(new ScanResult(cursor, results)); } default: { throw new Exception("error command:" + command + " unhandled:" + sourceBuffer[cursor] + " data:" + Encoding.UTF8.GetString(sourceBuffer)); } } return(new ScanResult(false)); }
private void StartReceiveAndSendDataAsync(DisqueCommand[] commands, byte[] data, Func <DisqueCommand, DisquuunResult[], bool> Callback) { #if LOGIC_BENCH { socketToken.currentCommands = commands; socketToken.currentSendingBytes = data; socketToken.AsyncCallback = Callback; socketToken.isPipeline = false; if (1 < commands.Length) { socketToken.isPipeline = true; pipelineIndex = 0; // -> PipelineReceive(token); { foreach (var command in commands) { var result = new DisquuunResult[0]; socketToken.AsyncCallback(command, result); } socketToken.socketState = SocketState.OPENED; SocketReloaded(this); } } else { // OnSend -> token.socketState = SocketState.SENDED; // receive -> Bench_LoopOrAsyncReceive(token); { Bench_LoopOrAsyncReceive(commands[0]); } } return; } #endif // ready for receive. socketToken.readableDataLength = 0; socketToken.receiveArgs.SetBuffer(socketToken.receiveBuffer, 0, socketToken.receiveBuffer.Length); if (!socketToken.socket.ReceiveAsync(socketToken.receiveArgs)) { OnReceived(socketToken.socket, socketToken.receiveArgs); } // if multiple commands exist, set as pipeline. socketToken.isPipeline = false; if (1 < commands.Length) { socketToken.isPipeline = true; pipelineIndex = 0; } socketToken.currentCommands = commands; socketToken.currentSendingBytes = data; socketToken.AsyncCallback = Callback; try { socketToken.sendArgs.SetBuffer(data, 0, data.Length); } catch { // renew. potential error is exists and should avoid this error. var sendArgs = new SocketAsyncEventArgs(); sendArgs.RemoteEndPoint = socketToken.receiveArgs.RemoteEndPoint; sendArgs.Completed += new EventHandler <SocketAsyncEventArgs>(OnSend); sendArgs.UserToken = socketToken; socketToken.sendArgs = sendArgs; socketToken.sendArgs.SetBuffer(data, 0, data.Length); } if (!socketToken.socket.SendAsync(socketToken.sendArgs)) { OnSend(socketToken.socket, socketToken.sendArgs); } }