internal void BufferTestReadInternal(ref MessageStream buf, string data, int start, int end, string fullData = null) { int bytes = data.Length * 2; string dataCheck; unsafe { fixed(MessageStream *bufPtr = &buf) { MessageStreamBuilder messageBuilder = new MessageStreamBuilder(bufPtr); fixed(char *d = data) { messageBuilder.WriteRaw((byte *)d, bytes); } } byte[] arr = buf.ToByteArray(start, end); fixed(byte *a = arr) { dataCheck = new string((char *)a, 0, arr.Length / 2); } } Assert.AreEqual((fullData ?? data).Substring(start / 2, (end - start) / 2), dataCheck); }
private void processStream(Stream stream) { MessageStream msgStream = new MessageStream(new StandardStream(stream)); Message msg = msgStream.readMessage(); if (msg == null) { return; } EMessageType mType = (EMessageType)msg.getType(); if (mType == EMessageType.eNumber) { // End a session MessageNumber response = new MessageNumber(msg); int sid = response.getNumber(); m_agent.signalToStopSession(sid); } else if (mType == EMessageType.ePidAndCompileRequest) { MessagePidAndCompileRequest request = new MessagePidAndCompileRequest(msg); TCompileResult cr = m_agent.compile(request.getPid(), request.getCmd(), request.getWorkingDir()); // The output file was already saved to local disk by the agent, now respond the result only msg = MessageCompileResponse.createMessage(cr.wasExec, cr.exitCode, cr.outputText, null, 0); msgStream.writeMessage(msg); } else { // WTF??? } }
public override bool TryGet(object[] parameter, out IReactiveStream <IMessage, bool> result) { if (parameter.Length == 0) { throw new IndexOutOfRangeException(); } if (!(parameter[0] is UInt32)) { throw new ArgumentOutOfRangeException("parameter"); } UInt32 id = (UInt32)parameter[0]; streamLock.WriteLock(); try { if (!streams.TryGetValue(id, out result)) { result = new MessageStream <IMessage> ( new PriorityDispatcher() ); streams.Add(id, result); } return(true); } finally { streamLock.WriteRelease(); } }
internal MessageWaiter(MessageStream stream, long expectedSequenceNumber, Store.IStoreReadWriteTransaction context, long traceId) { this.transactionContext = context; this.stream = stream; this.ExpectedSequenceNumber = expectedSequenceNumber; this.traceId = traceId; }
public void SendMessage() { try { RegisterMe(); ReceivedMessage = Send(null); if (ReceivedMessage != null && ReceivedMessage.Length <= 0) { ReceivedMessage = Receive(); } ReceivedModel = null; if (ReceivedMessage != null) { Parse(); ReceivedModel = _parser.Model; } if (ReceivedModel != null) { ProcessModel(); } } catch (Exception e) { WriteMessageProcessException(e, "Cannot process the message."); NotifyError(); } finally { if (MessageStream != null) { MessageStream.Close(); } UnregisterMe(); } }
private void signalToStopCompiling() { if (m_sid == 0) { return; } // Connect to the agent and send signal to stop NamedPipeClientStream pipeClient = new NamedPipeClientStream(".", Config.s_kAgentName); try { pipeClient.Connect(s_kPipeConnectTimeout); } catch (Exception) { return; } MessageStream stream = new MessageStream(new StandardStream(pipeClient)); Message msg = MessageNumber.createMessage(m_sid); if (!stream.writeMessage(msg)) { CConsole.writeError("error: could not send data to the mongcc agent.\n"); } pipeClient.Close(); }
/// <summary> /// Read Request /// </summary> /// <param name="request"></param> /// <returns></returns> protected override IQueueMessage ReadRequest(HttpRequestInfo request) { //throw new Exception("Not implemented."); MessageStream stream = null; if (request.BodyStream != null) { stream = MessageStream.ParseStream(request.BodyStream, NetProtocol.Http); } else { var message = new HttpMessage(); if (request.QueryString != null)//request.BodyType == HttpBodyType.QueryString) { message.EntityRead(request.QueryString, null); } else if (request.Body != null) { message.EntityRead(request.Body, null); } //else if (request.Url.LocalPath != null && request.Url.LocalPath.Length > 1) // message.EntityRead(request.Url.LocalPath.TrimStart('/').TrimEnd('/'), null); stream = message; } return(new QueueRequest(stream.GetStream())); }
public void BufferTestWriteBig() { // Should be in new node only, skipping head MessageStream buf = new MessageStream(16); BufferTestWriteInternal(ref buf, "abcdefgh ijk"); }
public async Task TestSimpleProtoBufStream() { var readStream = new MemoryStream(); var writeStream = new MemoryStream(); var messageStream = new MessageStream <object>( new ProtoBuf.ProtoBufMessageDeserializer(), new ProtoBuf.ProtoBufMessageSerializer(), new StreamDuplexMessageStream(readStream, writeStream) ); await messageStream.OpenAsync().ConfigureAwait(false); // Write two messages await messageStream.WriteAsync(new SimpleMessage { Id = 1, Value = 2 }).ConfigureAwait(false); await messageStream.WriteAsync(new SimpleMessage { Id = 2, Value = 4 }).ConfigureAwait(false); await messageStream.CloseAsync().ConfigureAwait(false); // Reset the streams position so we can read in the messages readStream = new MemoryStream(writeStream.ToArray()); readStream.Position = 0; writeStream = new MemoryStream(); messageStream = new MessageStream <object>( new ProtoBuf.ProtoBufMessageDeserializer(), new ProtoBuf.ProtoBufMessageSerializer(), new StreamDuplexMessageStream(readStream, writeStream) ); await messageStream.OpenAsync().ConfigureAwait(false); // Read the two messages var result = await messageStream.ReadAsync().ConfigureAwait(false); Assert.False(result.IsCompleted); Assert.IsType <SimpleMessage>(result.Result); var result2 = await messageStream.ReadAsync().ConfigureAwait(false); Assert.False(result2.IsCompleted); Assert.IsType <SimpleMessage>(result.Result); // This read should signal it's completed. var result3 = await messageStream.ReadAsync().ConfigureAwait(false); Assert.True(result3.IsCompleted); // Close await messageStream.CloseAsync().ConfigureAwait(false); }
public async Task Seek([FromOptionalArgument] double milliSeconds) { var resetData = new AmfObject { { "level", "status" }, { "code", "NetStream.Seek.Notify" }, { "description", "Seeking stream." }, { "details", "seek" } }; var resetStatus = RtmpSession.CreateCommandMessage <OnStatusCommandMessage>(); resetStatus.InfoObject = resetData; await MessageStream.SendMessageAsync(ChunkStream, resetStatus); _playCts?.Cancel(); while (_playing == 1) { await Task.Yield(); } var cts = new CancellationTokenSource(); _playCts?.Dispose(); _playCts = cts; await SeekAndPlay(milliSeconds, cts.Token); }
public UdpSocketReceiveEventArgs(UdpSocket socket, IPEndPoint remoteEndPoint, MessageStream message) { Socket = socket; RemoteEndPoint = remoteEndPoint; Message = message; }
protected override void Parse(ref BitStreamReader bsr) { PacketInfo = new CmdInfo[DemoInfo.MaxSplitscreenPlayers]; for (int i = 0; i < PacketInfo.Length; i++) { PacketInfo[i] = new CmdInfo(DemoRef); PacketInfo[i].ParseStream(ref bsr); } InSequence = bsr.ReadUInt(); OutSequence = bsr.ReadUInt(); MessageStream = new MessageStream(DemoRef); MessageStream.ParseStream(ref bsr); // After we're doing with the packet, we can process all the messages. // Most things should be processed during parsing, but any additional checks should be done here. var netTickMessages = MessageStream.Where(tuple => tuple.messageType == MessageType.NetTick).ToList(); if (netTickMessages.Count > 1) { DemoRef.LogError("there's more than 2 net tick messages in this packet"); } NetTick?tickInfo = (NetTick?)netTickMessages.FirstOrDefault().message; if (tickInfo != null) { if (DemoRef.EntitySnapshot != null) { DemoRef.EntitySnapshot.EngineTick = tickInfo.EngineTick; } } // todo fill prop handles with data here TimingAdjustment.AdjustFromPacket(this); }
public async Task TestStagedStreamAsync() { var readStream = new MemoryStream(); var writeStream = new MemoryStream(); var messageStream = new MessageStream <IStagedBodyMessage>( new MessageStreamReader(readStream), new StagedBodyMessageDeserializer( new MessageProvider <int, IStagedBodyMessage>(), new TestMessageDeserializer() ), new MessageStreamWriter(writeStream), new StagedBodyMessageSerializer( new TestMessageSerializer() ) ); await messageStream.OpenAsync().ConfigureAwait(false); // Write two messages await messageStream.WriteAsync(new TestMessage { Value = 2 }).ConfigureAwait(false); await messageStream.WriteAsync(new TestMessage { Value = 4 }).ConfigureAwait(false); await messageStream.CloseAsync().ConfigureAwait(false); // Reset the streams position so we can read in the messages writeStream.Position = 0; writeStream.CopyTo(readStream); readStream.Position = 0; await messageStream.OpenAsync().ConfigureAwait(false); // Read the two messages var result = await messageStream.ReadAsync().ConfigureAwait(false); Assert.False(result.IsCompleted); Assert.IsType <TestMessage>(result.Result); Assert.Equal(2, (result.Result as TestMessage).Value); var result2 = await messageStream.ReadAsync().ConfigureAwait(false); Assert.False(result2.IsCompleted); Assert.IsType <TestMessage>(result.Result); Assert.Equal(4, (result2.Result as TestMessage).Value); // This read should signal it's completed. var result3 = await messageStream.ReadAsync().ConfigureAwait(false); Assert.True(result3.IsCompleted); // Close await messageStream.CloseAsync().ConfigureAwait(false); }
/// <summary> /// Request 된 전문에 해당하는 Response 전문 생성 /// or /// 지정된 전문 생성 /// /// *** 보낼 SAEA 객체에는 Request 된 전문이 들어있음 /// </summary> /// <param name="sendEventArgs">보낼 SAEA 객체</param> /// <param name="packetName">옵션 : 특정전문 지정</param> /// <param name="userId">옵션 : 사용자 ID</param> /// <param name="message">옵션 : 메세지</param> /// <returns>MessageStream</returns> public MessageStream GetResponse(SocketAsyncEventArgs sendEventArgs, MessagePacketNameEnum packetName = MessagePacketNameEnum.EMPTY, string userId = "") { MessageStream response = null; try { /// Request 된 전문 (sendEventArgs) 에 해당하는 Response 전문 생성 if (packetName == MessagePacketNameEnum.EMPTY) { MessageReader reader = this.GetResponseHeader(sendEventArgs); response = this.GetResponseMake(sendEventArgs, reader); } else { //if (packetName == MessagePacketNameEnum.NTFTM) response = MessageNotifyTextMessage(sendEventArgs); if (packetName == MessagePacketNameEnum.ACCPT) { response = MessageAccept(); } else if (packetName == MessagePacketNameEnum.CLOSE) { response = MessageLoginDuplicated(userId); } } return(response); } catch { return(null); } }
public void RequestMessageStreamDeserialize() { StringBuilder sb = new StringBuilder(); sb.Append("<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>"); sb.Append("<messageStream>"); sb.Append("<message>"); sb.Append("<methodCall>"); sb.Append("<methodName>testMethod1</methodName>"); sb.Append("<params><param><value><boolean>1</boolean></value></param></params>"); sb.Append("</methodCall>"); sb.Append("</message>"); sb.Append("<message>"); sb.Append("<methodCall>"); sb.Append("<methodName>testMethod2</methodName>"); sb.Append("<params><param><value><string>test</string></value></param><param><value><boolean>0</boolean></value></param></params>"); sb.Append("</methodCall>"); sb.Append("</message>"); sb.Append("</messageStream>"); Message message = Deserialize(sb.ToString(), MessageType.Request); Assert.IsInstanceOf(typeof(MessageStream), message); MessageStream requestStream = (MessageStream)message; Assert.AreEqual(2, requestStream.MessageCount); }
// public void Setup(Action <Exception> cb) { // Cleanup any existing internal modules if (MessageStream != null) { MessageStream.Dispose(); } // Instantiate Singletons UnityApplicationState.Instantiate(); HttpRequestManager.Instantiate(); // Create a shared cookie container Cookies = new CookieContainer(); // Initialize mage internal modules EventManager = new EventManager(); CommandCenter = new Command.CommandCenter(); MessageStream = new MessageStream(); Session = new Session(); Archivist = new Archivist(); // Set endpoints CommandCenter.SetEndpoint(baseUrl, appName, headers); MessageStream.SetEndpoint(baseUrl, headers); cb(null); }
protected override Message Deserialize(BinaryReader reader, MessageType messageType) { int type = reader.ReadInt32(); if (type == 2) { MessageStream stream = new MessageStream(messageType); int sz = reader.ReadInt32(); for (int i = 0; i < sz; i++) { stream.AddMessage(Deserialize(reader, messageType)); } return stream as Message; } if (type == 1) { Message message; string messageName = reader.ReadString(); if (messageType == MessageType.Request) { message = new RequestMessage(messageName); } else { message = new ResponseMessage(messageName); } int sz = reader.ReadInt32(); for (int i = 0; i < sz; i++) message.Arguments.Add(ReadArgument(reader)); int v = reader.ReadInt32(); if (v != 8) throw new FormatException(); return message; } throw new FormatException("Unable to determine the format of the message."); }
public void Publish([FromOptionalArgument] string publishingName, [FromOptionalArgument] string publishingType) { if (string.IsNullOrEmpty(publishingName)) { throw new InvalidOperationException("empty publishing name"); } if (!PublishingHelpers.IsTypeSupported(publishingType)) { throw new InvalidOperationException($"not supported publishing type {publishingType}"); } _publishingType = PublishingHelpers.PublishingTypes[publishingType]; _publisherSessionService.RegisterPublisher(publishingName, this); RtmpSession.SendControlMessageAsync(new StreamBeginMessage() { StreamID = MessageStream.MessageStreamId }); var onStatus = RtmpSession.CreateCommandMessage <OnStatusCommandMessage>(); MessageStream.RegisterMessageHandler <DataMessage>(HandleDataMessage); MessageStream.RegisterMessageHandler <AudioMessage>(HandleAudioMessage); MessageStream.RegisterMessageHandler <VideoMessage>(HandleVideoMessage); onStatus.InfoObject = new AmfObject { { "level", "status" }, { "code", "NetStream.Publish.Start" }, { "description", "Stream is now published." }, { "details", publishingName } }; MessageStream.SendMessageAsync(ChunkStream, onStatus); }
public void BufferTestWriteExact() { // Should be in head only MessageStream buf = new MessageStream(16); BufferTestWriteInternal(ref buf, "abcdefgh"); }
/// <summary> /// 버전 정보 /// </summary> private static MessageStream MessageRequestVersionInfo(MessageReader reader) { DataTable dtResult = null; RESULT result = DbModule.Instance.FAS_CheckDeployInfo(reader.GetParam(0), ref dtResult); string repeatRowLength = dtResult.Rows.Count.ToString(); // row count string repeatColLength = "6"; // column count List <string> repeatList = new List <string>(); foreach (System.Data.DataRow dr in dtResult.Rows) { repeatList.Add(dr["BUILD_VER"].ToString()); repeatList.Add(dr["FILE_TYPE"].ToString()); repeatList.Add(dr["FILE_NAME"].ToString()); repeatList.Add(dr["FILE_SIZE"].ToString()); repeatList.Add(dr["FILE_SVR_PATH"].ToString()); repeatList.Add(dr["FILE_LOCAL_PATH"].ToString()); } /// 전문 생성 MessageStream response = MessageStream.Response(MessagePacketNameEnum.REQVI, reader.Header, repeatRowLength, repeatColLength); response.AddRepeater(repeatList.ToArray()); return(response); }
public void BufferTestWriteSmallBig() { // Should be in 2 nodes, including head MessageStream buf = new MessageStream(16); BufferTestWriteInternal(ref buf, "ab"); BufferTestWriteInternal(ref buf, "cdefgh ijklmnopqrs"); }
public void BufferTestWriteBigBig() { // Should be in 2 nodes, skipping head MessageStream buf = new MessageStream(16); BufferTestWriteInternal(ref buf, "abcdefghzyx "); BufferTestWriteInternal(ref buf, "ijklmnopqrs "); }
public async Task TestReadWriteAsync(LengthPrefixStyle lps) { using (var mem = new MemoryStream()) using (var stream = new MessageStream(mem, true, lps)) { await SubtestReadWriteAsync(stream, lps, () => stream?.Seek(0, SeekOrigin.Begin)); } }
public void BufferTestWriteSmallSmall() { // Should be in head only MessageStream buf = new MessageStream(16); BufferTestWriteInternal(ref buf, "ab"); BufferTestWriteInternal(ref buf, "cd"); }
public void TestReadWrite(LengthPrefixStyle lps) { using (var mem = new MemoryStream()) using (var stream = new MessageStream(mem, true, lps)) { SubtestReadWrite(stream, lps, () => stream?.Seek(0, SeekOrigin.Begin)); } }
public void OnMessage(IntPtr data, int len) { var ms = new MessageStream(data, len); var reader = ms.BeginRead(); var hellofromnim = reader.read_string(); Debug.Log(hellofromnim); }
public void BufferTestRecycleEmptyThrows() { MessageStream buf = new MessageStream(16); unsafe { Assert.Throws <ArgumentOutOfRangeException>(() => buf.RecyclePartialStream(buf.BufferRead, 4)); } }
public void BufferTestRecycleEmpty0DoesntThrow() { MessageStream buf = new MessageStream(16); unsafe { Assert.DoesNotThrow(() => buf.RecyclePartialStream(buf.BufferRead, 0)); } }
/// <summary> /// 로그인 /// </summary> private MessageStream MessageLogin(MessageReader reader, SocketAsyncEventArgs receiveSendEventArgs) { MessageStream response = null; string user_id = reader.GetParam(0); string user_pw = reader.GetParam(1); string user_name = ""; string recv_faxbox_id = ""; string send_faxbox_id = ""; /// ipep.ToString() : 100.100.106.230:2038 /// ipep.Address.ToString() : 100.100.106.230 IPEndPoint ipep = (IPEndPoint)receiveSendEventArgs.AcceptSocket.RemoteEndPoint; RESULT result = DbModule.Instance.FAS_LoginAgentClient(user_id, user_pw, ipep.ToString(), ref user_name, ref recv_faxbox_id, ref send_faxbox_id); if (result == RESULT.F_DB_NOTEXIST_USER_ID || result == RESULT.F_DB_PASSWORD_MISMATCH) { response = MessageStream.Response(MessagePacketNameEnum.LOGIN, reader.Header, false, "사용자 ID가 없거나 암호가 잘못되었습니다."); } else if (result == RESULT.SUCCESS || result == RESULT.F_DB_LOGIN_DUPLICATED) { /// /CLOSE 전문 발송 (중복 로그인) if (result == RESULT.F_DB_LOGIN_DUPLICATED) { FACInfo oldFacInfo = FACContainer.FindFACInfo(user_id); if (oldFacInfo != null) { if (this.OnLoginDuplicated != null) { this.OnLoginDuplicated(oldFacInfo); } } } DataHoldingUserToken receiveSendToken = (receiveSendEventArgs.UserToken as DataHoldingUserToken); /// Login 된 Client 로 추가 FACContainer.Update(receiveSendEventArgs.AcceptSocket, user_id, user_name); response = MessageStream.Response(MessagePacketNameEnum.LOGIN, reader.Header, "성공"); response.AddPrameters(reader.GetParam(0)); response.AddPrameters(user_name); response.AddPrameters(recv_faxbox_id); response.AddPrameters(send_faxbox_id); response.AddPrameters(((int)Config.CLIENT_ALIVE_INTERVAL).ToString()); response.AddPrameters(((int)Config.CLIENT_LIMIT_RESPONSE_TIME).ToString()); response.AddPrameters(Config.HOME_PATH_HTTP); } else { response = MessageStream.Response(MessagePacketNameEnum.LOGIN, reader.Header, false, result.ToString()); } return(response); }
public void BufferTestWriteBigSmallBig() { // Should be in 3 nodes, skipping head MessageStream buf = new MessageStream(16); BufferTestWriteInternal(ref buf, "abcdefghijk"); BufferTestWriteInternal(ref buf, "lm"); BufferTestWriteInternal(ref buf, "nopqrstuvwx"); }
static void Main(string[] args) { Subject subject = new MessageStream(); PhoneClient phoneClient = new PhoneClient(subject); TabletClient tabletClient = new TabletClient(subject); phoneClient.AddMessage("Here is a new message!"); tabletClient.AddMessage("Another new message!"); }
public void AddPath(IServiceAddress root, string pathName, string pathType) { InspectNetwork(); // Check machine is in the schema, MachineProfile machineProfile = CheckMachineInNetwork(root); if (!machineProfile.IsRoot) throw new NetworkAdminException("Machine '" + root + "' is not a root"); // Get the current manager server, MachineProfile man = ManagerServer; if (man == null) throw new NetworkAdminException("No manager server found"); // Check with the root server that the class instantiates, Message outputStream = new RequestMessage("checkPathType"); outputStream.Arguments.Add(pathType); Message m = Command(root, ServiceType.Root, outputStream); if (m.HasError) throw new NetworkAdminException("Type '" + pathType + "' doesn't instantiate on the root"); IServiceAddress managerServer = man.Address; // Create a new empty database, NetworkClient client = new NetworkClient(managerServer, connector); client.Connect(); DataAddress dataAddress = client.CreateEmptyDatabase(); client.Disconnect(); // Perform the command, outputStream = new MessageStream(MessageType.Request); RequestMessage request = new RequestMessage("addPath"); request.Arguments.Add(pathName); request.Arguments.Add(pathType); request.Arguments.Add(dataAddress); ((MessageStream)outputStream).AddMessage(request); request = new RequestMessage("initPath"); request.Arguments.Add(pathName); ((MessageStream)outputStream).AddMessage(request); Message message = Command(root, ServiceType.Root, outputStream); if (message.HasError) throw new NetworkAdminException(message.ErrorMessage); // Tell the manager server about this path, outputStream = new RequestMessage("addPathRootMapping"); outputStream.Arguments.Add(pathName); outputStream.Arguments.Add(root); message = Command(managerServer, ServiceType.Manager, outputStream); if (message.HasError) throw new NetworkAdminException(message.ErrorMessage); }
public void when_a_subscription_of_T_is_made_and_Push_of_T_is_called_then_the_subscription_is_called() { var messageStream = new MessageStream(); var result = false; messageStream.Of<bool>() .Subscribe(x => result = true); messageStream.Push(true); Assert.That(result, Is.True); }
public void when_a_subscription_of_T_is_made_and_Push_of_T_is_called_twice_then_the_subscription_is_called_twice() { var messageStream = new MessageStream(); var result = 1; messageStream.Of<bool>() .Subscribe(x => result++); messageStream.Push(true); Assert.That(result, Is.EqualTo(2)); }
public void when_two_subscriptions_of_T_are_made_and_Push_of_T_is_called_then_each_subscription_is_called() { var messageStream = new MessageStream(); var result1 = false; messageStream.Of<bool>() .Subscribe(x => result1 = true); var result2 = false; messageStream.Of<bool>() .Subscribe(x => result2 = true); messageStream.Push(true); Assert.That(result1, Is.True); Assert.That(result2, Is.True); }
private DataAddress InternalGetPathNow(PathInfo pathInfo, IServiceAddress rootServer) { MessageStream outputStream = new MessageStream(); outputStream.AddMessage(new Message("getPathNow", pathInfo.PathName, pathInfo.VersionNumber)); Message m = ProcessSingleRoot(outputStream, rootServer); if (m.HasError) throw new ApplicationException(m.ErrorMessage); return (DataAddress) m.Arguments[0].Value; }
protected PathInfo LoadFromManagers(string pathName, int pathInfoVersion) { IServiceAddress[] manSrvs = managerServers; PathInfo pathInfo = null; bool foundOne = false; // Query all the available manager servers for the path info, for (int i = 0; i < manSrvs.Length && pathInfo == null; ++i) { IServiceAddress managerService = manSrvs[i]; if (serviceTracker.IsServiceUp(managerService, ServiceType.Manager)) { MessageStream outputStream = new MessageStream(); outputStream.AddMessage(new Message("getPathInfoForPath", pathName)); IMessageProcessor processor = connector.Connect(managerService, ServiceType.Manager); IEnumerable<Message> result = processor.Process(outputStream); Message lastM = null; foreach (Message m in result) { if (m.HasError) { if (!ReplicatedValueStore.IsConnectionFault(m)) // If it's not a connection fault, we rethrow the error, throw new ApplicationException(m.ErrorMessage); serviceTracker.ReportServiceDownClientReport(managerService, ServiceType.Manager); } else { lastM = m; foundOne = true; } } if (lastM != null) { pathInfo = (PathInfo)lastM.Arguments[0].Value; } } } // If not received a valid reply from a manager service, generate exception if (foundOne == false) throw new ServiceNotConnectedException("Managers not available"); // Create and return the path info object, return pathInfo; }
private int SendCommand(List<ServiceMessageQueue> pendingQueue, List<IServiceAddress> machines, MessageStream outputStream) { // Send the messages, IEnumerable<Message>[] input = new IEnumerable<Message>[machines.Count]; // For each machine in the cluster, send the process commands, for (int x = 0; x < machines.Count; ++x) { IServiceAddress machine = machines[x]; IEnumerable<Message> inputStream = null; // If the service is up, if (tracker.IsServiceUp(machine, ServiceType.Manager)) { // Send to the service, IMessageProcessor processor = connector.Connect(machine, ServiceType.Manager); inputStream = processor.Process(outputStream); } input[x] = inputStream; } // Now read in the results. int sendCount = 0; int i = 0; while (i < input.Length) { bool msgSent = true; // Null indicates not sent, if (input[i] == null) { msgSent = false; } else { IEnumerator<Message> msgs = input[i].GetEnumerator(); while (msgs.MoveNext()) { Message m = msgs.Current; if (m.HasError) { // If it's not a comm fault, we throw the error now, if (!IsConnectionFault(m)) throw new ApplicationException(m.ErrorMessage); // Inform the tracker of the fault, tracker.ReportServiceDownClientReport(machines[i], ServiceType.Manager); msgSent = false; } } } // If not sent, queue the message, if (!msgSent) { // The machine that is not available, IServiceAddress machine = machines[i]; // Get the queue for the machine, ServiceMessageQueue queue = comm.CreateServiceMessageQueue(); queue.AddMessageStream(machine, outputStream, ServiceType.Manager); // Add this queue to the pending queue list pendingQueue.Add(queue); } else { // Otherwise we sent the message with no error, ++sendCount; } ++i; } return sendCount; }
private NodeId[] InternalPersist(TreeWrite sequence, int tryCount) { // NOTE: nodes are written in order of branches and then leaf nodes. All // branch nodes and leafs are grouped together. // The list of nodes to be allocated, IList<ITreeNode> allBranches = sequence.BranchNodes; IList<ITreeNode> allLeafs = sequence.LeafNodes; List<ITreeNode> nodes = new List<ITreeNode>(allBranches.Count + allLeafs.Count); nodes.AddRange(allBranches); nodes.AddRange(allLeafs); int sz = nodes.Count; // The list of allocated referenced for the nodes, DataAddress[] refs = new DataAddress[sz]; NodeId[] outNodeIds = new NodeId[sz]; MessageStream allocateMessageStream = new MessageStream(); // Allocate the space first, for (int i = 0; i < sz; ++i) { ITreeNode node = nodes[i]; // Is it a branch node? if (node is TreeBranch) { // Branch nodes are 1K in size, allocateMessageStream.AddMessage(new Message("allocateNode", 1024)); } // Otherwise, it must be a leaf node, else { // Leaf nodes are 4k in size, allocateMessageStream.AddMessage(new Message("allocateNode", 4096)); } } // Process a command on the manager, IEnumerable<Message> resultStream = ProcessManager(allocateMessageStream); // The unique list of blocks, List<BlockId> uniqueBlocks = new List<BlockId>(); // Parse the result stream one message at a time, the order will be the // order of the allocation messages, int n = 0; foreach (Message m in resultStream) { if (m.HasError) throw new ApplicationException(m.ErrorMessage); DataAddress addr = (DataAddress) m.Arguments[0].Value; refs[n] = addr; // Make a list of unique block identifiers, if (!uniqueBlocks.Contains(addr.BlockId)) { uniqueBlocks.Add(addr.BlockId); } ++n; } // Get the block to server map for each of the blocks, IDictionary<BlockId, IList<BlockServerElement>> blockToServerMap = GetServerListForBlocks(uniqueBlocks); // Make message streams for each unique block int ubidCount = uniqueBlocks.Count; MessageStream[] ubidStream = new MessageStream[ubidCount]; for (int i = 0; i < ubidStream.Length; ++i) { ubidStream[i] = new MessageStream(); } // Scan all the blocks and create the message streams, for (int i = 0; i < sz; ++i) { byte[] nodeBuf; ITreeNode node = nodes[i]; // Is it a branch node? if (node is TreeBranch) { TreeBranch branch = (TreeBranch) node; // Make a copy of the branch (NOTE; we clone() the array here). long[] curNodeData = (long[]) branch.NodeData.Clone(); int curNdsz = branch.NodeDataSize; branch = new TreeBranch(refs[i].Value, curNodeData, curNdsz); // The number of children int chsz = branch.ChildCount; // For each child, if it's a heap node, look up the child id and // reference map in the sequence and set the reference accordingly, for (int o = 0; o < chsz; ++o) { NodeId childId = branch.GetChild(o); if (childId.IsInMemory) { // The ref is currently on the heap, so adjust accordingly int refId = sequence.LookupRef(i, o); branch.SetChildOverride(refs[refId].Value, o); } } // Turn the branch into a 'node_buf' byte[] array object for // serialization. long[] nodeData = branch.NodeData; int ndsz = branch.NodeDataSize; MemoryStream bout = new MemoryStream(1024); BinaryWriter dout = new BinaryWriter(bout); dout.Write(StoreBranchType); dout.Write((short) 0); // Reserved for future dout.Write(0); // The crc32 checksum will be written here, dout.Write(ndsz); for (int o = 0; o < ndsz; ++o) { dout.Write(nodeData[o]); } dout.Flush(); // Turn it into a byte array, nodeBuf = bout.ToArray(); // Write the crc32 of the data, Crc32 checksum = new Crc32(); checksum.ComputeHash(nodeBuf, 8, nodeBuf.Length - 8); ByteBuffer.WriteInt4((int) checksum.CrcValue, nodeBuf, 4); // Put this branch into the local cache, networkCache.SetNode(refs[i], branch); } // If it's a leaf node, else { TreeLeaf leaf = (TreeLeaf) node; int lfsz = leaf.Length; nodeBuf = new byte[lfsz + 12]; // Format the data, ByteBuffer.WriteInt2(StoreLeafType, nodeBuf, 0); ByteBuffer.WriteInt2(0, nodeBuf, 2); // Reserved for future ByteBuffer.WriteInt4(lfsz, nodeBuf, 8); leaf.Read(0, nodeBuf, 12, lfsz); // Calculate and set the checksum, Crc32 checksum = new Crc32(); checksum.ComputeHash(nodeBuf, 8, nodeBuf.Length - 8); ByteBuffer.WriteInt4((int) checksum.CrcValue, nodeBuf, 4); // Put this leaf into the local cache, leaf = new MemoryTreeLeaf(refs[i].Value, nodeBuf); networkCache.SetNode(refs[i], leaf); } // The DataAddress this node is being written to, DataAddress address = refs[i]; // Get the block id, BlockId blockId = address.BlockId; int bid = uniqueBlocks.IndexOf(blockId); ubidStream[bid].AddMessage(new Message("writeToBlock", address, nodeBuf, 0, nodeBuf.Length)); // Update 'out_refs' array, outNodeIds[i] = refs[i].Value; } // A log of successfully processed operations, List<object> successProcess = new List<object>(64); // Now process the streams on the servers, for (int i = 0; i < ubidStream.Length; ++i) { // The output message, MessageStream outputStream = ubidStream[i]; // Get the servers this message needs to be sent to, BlockId blockId = uniqueBlocks[i]; IList<BlockServerElement> blockServers = blockToServerMap[blockId]; // Format a message for writing this node out, int bssz = blockServers.Count; IMessageProcessor[] blockServerProcs = new IMessageProcessor[bssz]; // Make the block server connections, for (int o = 0; o < bssz; ++o) { IServiceAddress address = blockServers[o].Address; blockServerProcs[o] = connector.Connect(address, ServiceType.Block); IEnumerable<Message> inputStream = blockServerProcs[o].Process(outputStream); ++NetworkCommCount; foreach (Message m in inputStream) { if (m.HasError) { // If this is an error, we need to report the failure to the // manager server, ReportBlockServerFailure(address); // Remove the block id from the server list cache, networkCache.RemoveServersWithBlock(blockId); // Rollback any server writes already successfully made, for (int p = 0; p < successProcess.Count; p += 2) { IServiceAddress blocksAddr = (IServiceAddress) successProcess[p]; MessageStream toRollback = (MessageStream) successProcess[p + 1]; List<DataAddress> rollbackNodes = new List<DataAddress>(128); foreach (Message rm in toRollback) { DataAddress raddr = (DataAddress) rm.Arguments[0].Value; rollbackNodes.Add(raddr); } // Create the rollback message, MessageStream rollbackMsg = new MessageStream(); rollbackMsg.AddMessage(new Message("rollbackNodes", new object[] {rollbackNodes.ToArray()})); // Send it to the block server, IEnumerable<Message> responseStream = connector.Connect(blocksAddr, ServiceType.Block).Process(rollbackMsg); ++NetworkCommCount; foreach (Message rbm in responseStream) { // If rollback generated an error we throw the error now // because this likely is a serious network error. if (rbm.HasError) { throw new NetworkWriteException("Write failed (rollback failed): " + rbm.ErrorMessage); } } } // Retry, if (tryCount > 0) return InternalPersist(sequence, tryCount - 1); // Otherwise we fail the write throw new NetworkWriteException(m.ErrorMessage); } } // If we succeeded without an error, add to the log successProcess.Add(address); successProcess.Add(outputStream); } } // Return the references, return outNodeIds; }
public IEnumerable<Message> Process(IEnumerable<Message> stream) { // The reply message, MessageStream replyMessage = new MessageStream(); // The messages in the stream, foreach (Message m in stream) { try { // Check the server isn't in a stop state, service.CheckErrorState(); String cmd = m.Name; // getServerList(BlockId) if (cmd.Equals("getServerList")) { BlockServiceInfo[] servers = GetServerList((BlockId) m.Arguments[0].Value); Message response = new Message(); response.Arguments.Add(servers.Length); for (int i = 0; i < servers.Length; ++i) { response.Arguments.Add(servers[i].Address); response.Arguments.Add(service.serviceTracker.GetServiceCurrentStatus(servers[i].Address, ServiceType.Block)); } replyMessage.AddMessage(response); } // allocateNode(int node_size) else if (cmd.Equals("allocateNode")) { DataAddress address = AllocateNode((int) m.Arguments[0].Value); replyMessage.AddMessage(new Message(address)); } // registerBlockServer(ServiceAddress service_address) else if (cmd.Equals("registerBlockServer")) { service.RegisterBlockServer((IServiceAddress) m.Arguments[0].Value); replyMessage.AddMessage(new Message(1)); } // deregisterBlockServer(IServiceAddress) else if (cmd.Equals("deregisterBlockServer")) { service.DeregisterBlockServer((IServiceAddress) m.Arguments[0].Value); replyMessage.AddMessage(new Message(1)); } // deregisterAllBlockServers() else if (cmd.Equals("deregisterAllBlockServers")) { service.DeregisterAllBlockServers(); replyMessage.AddMessage(new Message(1)); } // registerManagerServers(ServiceAddress[] managers) else if (cmd.Equals("registerManagerServers")) { service.RegisterManagerServers((IServiceAddress[]) m.Arguments[0].Value); replyMessage.AddMessage(new Message(1)); } // deregisterAllManagerServers() else if (cmd.Equals("deregisterManagerServer")) { service.DeregisterManagerServer((IServiceAddress) m.Arguments[0].Value); replyMessage.AddMessage(new Message(1)); } // addPathToNetwork(string, string, IServiceAddress, IServiceAddress[]) else if (cmd.Equals("addPathToNetwork")) { service.AddPathToNetwork((string) m.Arguments[0].Value, (string) m.Arguments[1].Value, (IServiceAddress) m.Arguments[2].Value, (IServiceAddress[]) m.Arguments[3].Value); replyMessage.AddMessage(new Message(1)); } // removePathFromNetwork(String path_name) else if (cmd.Equals("removePathFromNetwork")) { service.RemovePathFromNetwork((string) m.Arguments[0].Value); replyMessage.AddMessage(new Message(1)); } // addBlockServerMapping(BlockId, long[]) else if (cmd.Equals("internalAddBlockServerMapping")) { service.InternalAddBlockServerMapping((BlockId) m.Arguments[0].Value, (long[]) m.Arguments[1].Value); replyMessage.AddMessage(new Message(1)); } // removeBlockServerMapping(BlockId, long[]) else if (cmd.Equals("internalRemoveBlockServerMapping")) { service.InternalRemoveBlockServerMapping((BlockId) m.Arguments[0].Value, (long[]) m.Arguments[1].Value); replyMessage.AddMessage(new Message(1)); } // --- Path processors --- // registerRootServer(IServiceAddress) else if (cmd.Equals("registerRootServer")) { service.RegisterRootServer((IServiceAddress) m.Arguments[0].Value); replyMessage.AddMessage(new Message(1)); } // deregisterRootServer(IServiceAddress) else if (cmd.Equals("deregisterRootServer")) { service.DeregisterRootServer((IServiceAddress) m.Arguments[0].Value); replyMessage.AddMessage(new Message(1)); } // deregisterAllConsensusProcessors() else if (cmd.Equals("deregisterAllRootServers")) { service.DeregisterAllRootServers(); replyMessage.AddMessage(new Message(1)); } // PathInfo getPathInfoForPath(string) else if (cmd.Equals("getPathInfoForPath")) { PathInfo pathInfo = service.GetPathInfoForPath((String) m.Arguments[0].Value); replyMessage.AddMessage(new Message(pathInfo)); } // string[] getAllPaths() else if (cmd.Equals("getAllPaths")) { string[] pathSet = service.GetAllPaths(); replyMessage.AddMessage(new Message(new object[] {pathSet})); } // getRegisteredServerList() else if (cmd.Equals("getRegisteredServerList")) { GetRegisteredServerList(replyMessage); } // getRegisteredBlockServers() else if (cmd.Equals("getRegisteredBlockServers")) { GetRegisteredBlockServers(replyMessage); } // getRegisteredRootServers() else if (cmd.Equals("getRegisteredRootServers")) { GetRegisteredRootServers(replyMessage); } // notifyBlockServerFailure(IServiceAddress) else if (cmd.Equals("notifyBlockServerFailure")) { service.NotifyBlockServerFailure((IServiceAddress) m.Arguments[0].Value); replyMessage.AddMessage(new Message(1)); } // notifyBlockIdCorruption(IServiceAddress, BlockId, string) else if (cmd.Equals("notifyBlockIdCorruption")) { service.NotifyBlockIdCorruption((IServiceAddress) m.Arguments[0].Value, (BlockId) m.Arguments[1].Value, (string) m.Arguments[2].Value); replyMessage.AddMessage(new Message(1)); } // getUniqueId() else if (cmd.Equals("getUniqueId")) { long uniqueId = service.managerUniqueId; replyMessage.AddMessage(new Message(uniqueId)); } // poll(String) else if (m.Name.Equals("poll")) { service.managerDb.CheckConnected(); replyMessage.AddMessage(new Message(1)); } else { // Defer to the manager db process command, service.managerDb.Process(m, replyMessage); } } catch (OutOfMemoryException e) { service.Logger.Error("Memory Error", e); service.SetErrorState(e); throw; } catch (Exception e) { service.Logger.Error("Exception during process", e); replyMessage.AddMessage(new Message(new MessageError(e))); } } return replyMessage; }
public void Process(Message m, MessageStream replyMessage) { String cmd = m.Name; if (cmd.Equals("internalKVProposal")) { long[] uid = (long[]) m.Arguments[0].Value; String key = (String) m.Arguments[1].Value; String value = (String) m.Arguments[2].Value; InternalKvProposal(uid, key, value); replyMessage.AddMessage(new Message(1)); } else if (cmd.Equals("internalKVComplete")) { long[] uid = (long[]) m.Arguments[0].Value; String key = (String) m.Arguments[1].Value; String value = (String) m.Arguments[2].Value; InternalKvComplete(uid, key, value); replyMessage.AddMessage(new Message(1)); } else if (cmd.Equals("internalBSProposal")) { long[] uid = (long[]) m.Arguments[0].Value; BlockId blockId = (BlockId) m.Arguments[1].Value; long[] serverUids = (long[]) m.Arguments[2].Value; InternalBsProposal(uid, blockId, serverUids); replyMessage.AddMessage(new Message(1)); } else if (cmd.Equals("internalBSComplete")) { long[] uid = (long[]) m.Arguments[0].Value; BlockId blockId = (BlockId) m.Arguments[1].Value; long[] serverUids = (long[]) m.Arguments[2].Value; InternalBsComplete(uid, blockId, serverUids); replyMessage.AddMessage(new Message(1)); } else if (cmd.Equals("internalFetchLogBundle")) { long[] uid = (long[]) m.Arguments[0].Value; bool initial = ((int) m.Arguments[1].Value) != 0; InternalFetchLogBundle(replyMessage, uid, initial); } else if (cmd.Equals("debugString")) { StringWriter strOut = new StringWriter(); DebugOutput(strOut); strOut.Flush(); replyMessage.AddMessage(new Message(strOut.ToString())); } else { throw new ApplicationException("Unknown command: " + m.Name); } }
private Message Deserialize(XmlReader xmlReader, MessageType messageType) { Message message = null; while (xmlReader.Read()) { XmlNodeType nodeType = xmlReader.NodeType; if (nodeType == XmlNodeType.DocumentType || nodeType == XmlNodeType.Document || nodeType == XmlNodeType.Comment || nodeType == XmlNodeType.XmlDeclaration) continue; if (nodeType == XmlNodeType.Element) { string elementName = xmlReader.LocalName; if (message == null) { if (elementName == "methodCall") { if (!xmlReader.Read()) throw new FormatException(); if (xmlReader.NodeType != XmlNodeType.Element) throw new FormatException("Invalid node type found."); if (xmlReader.LocalName != "methodName") throw new FormatException("Unexpected element name."); if (!xmlReader.Read()) throw new FormatException("Method name not found."); if (xmlReader.NodeType != XmlNodeType.Text) throw new FormatException("Invalid content in method name element."); message = new RequestMessage(xmlReader.Value); } else if (elementName == "methodResponse") { message = new ResponseMessage(); } else if (elementName == "messageStream") { message = new MessageStream(messageType); while (xmlReader.Read()) { if (xmlReader.NodeType == XmlNodeType.EndElement) { if (xmlReader.LocalName == "message") continue; if (xmlReader.LocalName == "messageStream") break; } ((MessageStream)message).AddMessage(Deserialize(xmlReader, messageType)); } } else { throw new FormatException("Invalid root element name."); } } else if (xmlReader.LocalName == "fault") { if (messageType != MessageType.Response) throw new FormatException("Fault element found in a request message."); object value = ReadValue(xmlReader); if (!(value is MessageError)) throw new FormatException(); } else if (xmlReader.LocalName == "params") { ReadParams(message, xmlReader); } else { throw new FormatException("Invalid element name."); } } else if (nodeType == XmlNodeType.EndElement) { string elementName = xmlReader.LocalName; if (elementName == "methodCall" || elementName == "methodResponse") break; continue; } else { throw new FormatException("Invalid node type."); } } if (message == null) throw new FormatException("Invalid format"); if (message.MessageType != messageType) throw new FormatException("The returned message is not expected."); return message; }
private void PollAllRootMachines(IServiceAddress[] machines) { // Create the message, MessageStream outputStream = new MessageStream(); outputStream.AddMessage(new Message("poll", "RSPoll")); for (int i = 0; i < machines.Length; ++i) { IServiceAddress machine = machines[i]; // If the service is up in the tracker, if (serviceTracker.IsServiceUp(machine, ServiceType.Root)) { // Poll it to see if it's really up. // Send the poll to the service, IMessageProcessor processor = connector.Connect(machine, ServiceType.Root); IEnumerable<Message> inputStream = processor.Process(outputStream); // If return is a connection fault, foreach (Message m in inputStream) { if (m.HasError && ReplicatedValueStore.IsConnectionFault(m)) { serviceTracker.ReportServiceDownClientReport(machine, ServiceType.Root); } } } } }
private IDictionary<BlockId, IList<BlockServerElement>> GetServerListForBlocks(List<BlockId> blockIds) { // The result map, Dictionary<BlockId, IList<BlockServerElement>> resultMap = new Dictionary<BlockId, IList<BlockServerElement>>(); List<BlockId> noneCached = new List<BlockId>(blockIds.Count); foreach (BlockId blockId in blockIds) { IList<BlockServerElement> v = networkCache.GetServersWithBlock(blockId); // If it's cached (and the cache is current), if (v != null) { resultMap.Add(blockId, v); } // If not cached, add to the list of none cached entries, else { noneCached.Add(blockId); } } // If there are no 'none_cached' blocks, if (noneCached.Count == 0) { // Return the result, return resultMap; } // Otherwise, we query the manager server for current records on the given // blocks. MessageStream outputStream = new MessageStream(); foreach (BlockId blockId in noneCached) { outputStream.AddMessage(new Message("getServerList", blockId)); } // Process a command on the manager, IEnumerable<Message> inputStream = ProcessManager(outputStream); int n = 0; foreach (Message m in inputStream) { if (m.HasError) throw new ApplicationException(m.ErrorMessage); int sz = (int) m.Arguments[0].Value; List<BlockServerElement> srvs = new List<BlockServerElement>(sz); for (int i = 0; i < sz; ++i) { IServiceAddress address = (IServiceAddress) m.Arguments[1 + (i*2)].Value; ServiceStatus status = (ServiceStatus) m.Arguments[1 + (i*2) + 1].Value; srvs.Add(new BlockServerElement(address, status)); } // Shuffle the list CollectionsUtil.Shuffle(srvs); // Move the server closest to this node to the start of the list, int closest = 0; int curCloseFactor = Int32.MaxValue; for (int i = 0; i < sz; ++i) { BlockServerElement elem = srvs[i]; int closenessFactor = FindClosenessToHere(elem.Address); if (closenessFactor < curCloseFactor) { curCloseFactor = closenessFactor; closest = i; } } // Swap if necessary, if (closest > 0) CollectionsUtil.Swap(srvs, 0, closest); // Put it in the result map, BlockId blockId = noneCached[n]; resultMap[blockId] = srvs; // Add it to the cache, // NOTE: TTL hard-coded to 15 minute networkCache.SetServersForBlock(blockId, srvs, 15*60*1000); ++n; } // Return the list return resultMap; }
private List<long> DoPersist(TreeWrite sequence, int tryCount) { // NOTE: nodes are written in order of branches and then leaf nodes. All // branch nodes and leafs are grouped together. // The list of nodes to be allocated, IList<ITreeNode> allBranches = sequence.BranchNodes; IList<ITreeNode> allLeafs = sequence.LeafNodes; List<ITreeNode> nodes = new List<ITreeNode>(allBranches.Count + allLeafs.Count); nodes.AddRange(allBranches); nodes.AddRange(allLeafs); int sz = nodes.Count; // The list of allocated referenced for the nodes, DataAddress[] refs = new DataAddress[sz]; long[] outRefs = new long[sz]; MessageStream allocateMessage = new MessageStream(MessageType.Request); // Make a connection with the manager server, IMessageProcessor manager = connector.Connect(managerAddress, ServiceType.Manager); // Allocate the space first, for (int i = 0; i < sz; ++i) { ITreeNode node = nodes[i]; RequestMessage request = new RequestMessage("allocateNode"); // Is it a branch node? if (node is TreeBranch) { // Branch nodes are 1K in size, request.Arguments.Add(1024); } else { // Leaf nodes are 4k in size, request.Arguments.Add(4096); } allocateMessage.AddMessage(request); } // The result of the set of allocations, MessageStream resultStream = (MessageStream) manager.Process(allocateMessage); //DEBUG: ++network_comm_count; // The unique list of blocks, List<long> uniqueBlocks = new List<long>(); // Parse the result stream one message at a time, the order will be the // order of the allocation messages, int n = 0; foreach (ResponseMessage m in resultStream) { if (m.HasError) throw m.Error.AsException(); DataAddress addr = (DataAddress) m.Arguments[0].Value; refs[n] = addr; // Make a list of unique block identifiers, if (!uniqueBlocks.Contains(addr.BlockId)) { uniqueBlocks.Add(addr.BlockId); } ++n; } // Get the block to server map for each of the blocks, IDictionary<long, IList<BlockServerElement>> blockToServerMap = GetServersForBlock(uniqueBlocks); // Make message streams for each unique block int ubid_count = uniqueBlocks.Count; MessageStream[] ubidStream = new MessageStream[ubid_count]; for (int i = 0; i < ubidStream.Length; ++i) { ubidStream[i] = new MessageStream(MessageType.Request); } // Scan all the blocks and create the message streams, for (int i = 0; i < sz; ++i) { byte[] nodeBuf; ITreeNode node = nodes[i]; // Is it a branch node? if (node is TreeBranch) { TreeBranch branch = (TreeBranch)node; // Make a copy of the branch (NOTE; we Clone() the array here). long[] curNodeData = (long[])branch.ChildPointers.Clone(); int curNdsz = branch.DataSize; branch = new TreeBranch(refs[i].Value, curNodeData, curNdsz); // The number of children int chsz = branch.ChildCount; // For each child, if it's a heap node, look up the child id and // reference map in the sequence and set the reference accordingly, for (int o = 0; o < chsz; ++o) { long childRef = branch.GetChild(o); if (childRef < 0) { // The ref is currently on the heap, so adjust accordingly int ref_id = sequence.LookupRef(i, o); branch.SetChildOverride(o, refs[ref_id].Value); } } // Turn the branch into a 'node_buf' byte[] array object for // serialization. long[] nodeData = branch.ChildPointers; int ndsz = branch.DataSize; MemoryStream bout = new MemoryStream(1024); BinaryWriter dout = new BinaryWriter(bout, Encoding.Unicode); dout.Write(BranchType); dout.Write(ndsz); for (int o = 0; o < ndsz; ++o) { dout.Write(nodeData[o]); } dout.Flush(); // Turn it into a byte array, nodeBuf = bout.ToArray(); // Put this branch into the local cache, networkCache.SetNode(refs[i], branch); } else { // If it's a leaf node, TreeLeaf leaf = (TreeLeaf)node; int lfsz = leaf.Length; nodeBuf = new byte[lfsz + 6]; // Technically, we could comment these next two lines out. ByteBuffer.WriteInt2(LeafType, nodeBuf, 0); ByteBuffer.WriteInt4(lfsz, nodeBuf, 2); leaf.Read(0, nodeBuf, 6, lfsz); // Put this leaf into the local cache, leaf = new ByteArrayTreeLeaf(refs[i].Value, nodeBuf); networkCache.SetNode(refs[i], leaf); } // The DataAddress this node is being written to, DataAddress address = refs[i]; // Get the block id, long blockId = address.BlockId; int bid = uniqueBlocks.IndexOf(blockId); RequestMessage request = new RequestMessage("writeToBlock"); request.Arguments.Add(address); request.Arguments.Add(nodeBuf); request.Arguments.Add(0); request.Arguments.Add(nodeBuf.Length); ubidStream[bid].AddMessage(request); // Update 'outRefs' array, outRefs[i] = refs[i].Value; } // A log of successfully processed operations, List<object> successProcess = new List<object>(64); // Now process the streams on the servers, for (int i = 0; i < ubidStream.Length; ++i) { // The output message, MessageStream requestMessageStream = ubidStream[i]; // Get the servers this message needs to be sent to, long block_id = uniqueBlocks[i]; IList<BlockServerElement> blockServers = blockToServerMap[block_id]; // Format a message for writing this node out, int bssz = blockServers.Count; IMessageProcessor[] blockServerProcs = new IMessageProcessor[bssz]; // Make the block server connections, for (int o = 0; o < bssz; ++o) { IServiceAddress address = blockServers[o].Address; blockServerProcs[o] = connector.Connect(address, ServiceType.Block); MessageStream responseMessageStream = (MessageStream) blockServerProcs[o].Process(requestMessageStream); //DEBUG: ++network_comm_count; if (responseMessageStream.HasError) { // If this is an error, we need to report the failure to the // manager server, ReportBlockServerFailure(address); // Remove the block id from the server list cache, networkCache.RemoveServers(block_id); // Rollback any server writes already successfully made, for (int p = 0; p < successProcess.Count; p += 2) { IServiceAddress blockAddress = (IServiceAddress) successProcess[p]; MessageStream toRollback = (MessageStream) successProcess[p + 1]; List<DataAddress> rollbackNodes = new List<DataAddress>(128); foreach(Message rm in toRollback) { DataAddress raddr = (DataAddress) rm.Arguments[0].Value; rollbackNodes.Add(raddr); } // Create the rollback message, RequestMessage rollbackRequest = new RequestMessage("rollbackNodes"); rollbackRequest.Arguments.Add(rollbackNodes.ToArray()); // Send it to the block server, Message responseMessage = connector.Connect(blockAddress, ServiceType.Block).Process(rollbackRequest); //DEBUG: ++network_comm_count; // If rollback generated an error we throw the error now // because this likely is a serious network error. if (responseMessage.HasError) throw new NetworkException("Rollback wrote failed: " + responseMessage.ErrorMessage); } // Retry, if (tryCount > 0) return DoPersist(sequence, tryCount - 1); // Otherwise we fail the write throw new NetworkException(responseMessageStream.ErrorMessage); } // If we succeeded without an error, add to the log successProcess.Add(address); successProcess.Add(requestMessageStream); } } // Return the references, return new List<long>(outRefs); }
private void GetRegisteredServerList(MessageStream outputStream) { // Populate the list of registered servers IServiceAddress[] srvs; ServiceStatus[] statusCodes; lock (service.blockServersMap) { int sz = service.blockServersList.Count; srvs = new IServiceAddress[sz]; statusCodes = new ServiceStatus[sz]; int i = 0; foreach (BlockServiceInfo m in service.blockServersList) { srvs[i] = m.Address; statusCodes[i] = service.serviceTracker.GetServiceCurrentStatus(m.Address, ServiceType.Block); ++i; } } // Populate the reply message, outputStream.AddMessage(new Message(srvs, statusCodes)); }
//TODO: private Message Deserialize(JsonReader reader, MessageType messageType) { Message message = null; while (reader.Read()) { JsonToken jsonToken = reader.Token; if (jsonToken == JsonToken.ObjectStart) continue; if (jsonToken == JsonToken.ObjectEnd) return message; if (jsonToken == JsonToken.PropertyName) { string propertyName = (string) reader.Value; if (String.IsNullOrEmpty(propertyName)) throw new FormatException(); if (message == null) { if (propertyName == "jsonrpc") { if (!reader.Read()) throw new FormatException(); if (reader.Token != JsonToken.String) throw new FormatException(); if ((string)reader.Value != "1.0") throw new FormatException("JSON RPC protocol version not supported."); } else if (propertyName == "method") { if (!reader.Read()) throw new FormatException(); if (reader.Token != JsonToken.String) throw new FormatException("Expected method name."); message = new RequestMessage((string) reader.Value); } else if (propertyName == "result") { if (messageType != MessageType.Response) throw new FormatException("Unexpected result message."); message = new ResponseMessage(); } else if (propertyName == "error") { if (messageType != MessageType.Response) throw new FormatException("Unexpected error result message."); message = new ResponseMessage(); message.Arguments.Add(ReadMessageError(reader)); } else if (propertyName == "stream") { // Addition to support IRPC message = new MessageStream(messageType); while (reader.Read()) { if (reader.Token == JsonToken.ObjectEnd) break; ((MessageStream)message).AddMessage(Deserialize(reader, messageType)); } return message; } } else if (propertyName == "params") { if (!reader.Read()) throw new FormatException(); if (reader.Token != JsonToken.ArrayStart) throw new FormatException(); while (reader.Read()) { if (reader.Token == JsonToken.ArrayEnd) break; message.Arguments.Add(ReadValue(reader)); } } } } return message; }
private void GetRegisteredRootServers(MessageStream outputStream) { // Populate the list of registered root servers IServiceAddress[] srvs; lock (service.rootServersList) { int sz = service.rootServersList.Count; srvs = new IServiceAddress[sz]; int i = 0; foreach (RootServiceInfo m in service.rootServersList) { srvs[i] = m.Address; ++i; } } // The reply message, outputStream.AddMessage(new Message(new object[] {srvs})); }
public IEnumerable<Message> Process(IEnumerable<Message> stream) { // The reply message, MessageStream replyMessage = new MessageStream(); // The messages in the stream, foreach (Message m in stream) { try { service.CheckErrorState(); // publishPath(string, long, DataAddress) if (m.Name.Equals("publishPath")) { PublishPath((String) m.Arguments[0].Value, (int) m.Arguments[1].Value, (DataAddress) m.Arguments[2].Value); replyMessage.AddMessage(new Message(1L)); } // DataAddress getPathNow(String, long) else if (m.Name.Equals("getPathNow")) { DataAddress dataAddress = GetPathNow((string)m.Arguments[0].Value, (int)m.Arguments[1].Value); replyMessage.AddMessage(new Message(dataAddress)); } // DataAddress[] getPathHistorical(string, long, long, long) else if (m.Name.Equals("getPathHistorical")) { DataAddress[] dataAddresses = GetPathHistorical((string) m.Arguments[0].Value, (int) m.Arguments[1].Value, (long) m.Arguments[2].Value, (long) m.Arguments[3].Value); replyMessage.AddMessage(new Message(new object[] {dataAddresses})); } // long getCurrentTimeMillis() else if (m.Name.Equals("getCurrentTimeMillis")) { long timeMillis = DateTimeUtil.CurrentTimeMillis(); replyMessage.AddMessage(new Message(timeMillis)); } // commit(string, long, DataAddress) else if (m.Name.Equals("commit")) { DataAddress result = Commit((string) m.Arguments[0].Value, (int) m.Arguments[1].Value, (DataAddress) m.Arguments[2].Value); replyMessage.AddMessage(new Message(result)); } // getPathType(String path) else if (m.Name.Equals("getPathType")) { string pathType = service.GetPathType((string)m.Arguments[0].Value); replyMessage.AddMessage(new Message(pathType)); } // initialize(string, long) else if (m.Name.Equals("initialize")) { Initialize((string)m.Arguments[0].Value, (int)m.Arguments[1].Value); replyMessage.AddMessage(new Message(1L)); } // getPathStats(string, long) else if (m.Name.Equals("getPathStats")) { String stats = GetPathStats((string)m.Arguments[0].Value, (int)m.Arguments[1].Value); replyMessage.AddMessage(new Message(stats)); } // getSnapshotStats(string, long, DataAddress) else if (m.Name.Equals("getSnapshotStats")) { String stats = GetSnapshotStats((string)m.Arguments[0].Value, (int)m.Arguments[1].Value, (DataAddress)m.Arguments[2].Value); replyMessage.AddMessage(new Message(stats)); } // checkCPathType(string) else if (m.Name.Equals("checkPathType")) { CheckPathType((string)m.Arguments[0].Value); replyMessage.AddMessage(new Message(1)); } // informOfManagers(ServiceAddress[] manager_servers) else if (m.Name.Equals("informOfManagers")) { service.OnManagersSet((IServiceAddress[])m.Arguments[0].Value); replyMessage.AddMessage(new Message(1L)); } // clearOfManagers() else if (m.Name.Equals("clearOfManagers")) { service.OnManagersClear(); replyMessage.AddMessage(new Message(1L)); } // loadPathInfo(PathInfo) else if (m.Name.Equals("loadPathInfo")) { service.LoadPathInfo((PathInfo)m.Arguments[0].Value); replyMessage.AddMessage(new Message(1L)); } // notifyNewProposal(string, long, DataAddress) else if (m.Name.Equals("notifyNewProposal")) { service.NotifyNewProposal((string) m.Arguments[0].Value, (long) m.Arguments[1].Value, (DataAddress) m.Arguments[2].Value); replyMessage.AddMessage(new Message(1L)); } // internalSetPathInfo(String path_name, long ver, PathInfo path_info) else if (m.Name.Equals("internalSetPathInfo")) { service.InternalSetPathInfo((string) m.Arguments[0].Value, (int) m.Arguments[1].Value, (PathInfo) m.Arguments[2].Value); replyMessage.AddMessage(new Message(1L)); } // internalFetchPathDataBundle(String path_name, // long uid, DataAddress addr) else if (m.Name.Equals("internalFetchPathDataBundle")) { object[] r = service.InternalFetchPathDataBundle((string) m.Arguments[0].Value, (long) m.Arguments[1].Value, (DataAddress) m.Arguments[2].Value); replyMessage.AddMessage(new Message(r)); } // poll() else if (m.Name.Equals("poll")) { replyMessage.AddMessage(new Message(1)); } else { throw new ApplicationException("Unknown command: " + m.Name); } } catch (OutOfMemoryException e) { service.Logger.Error("Memory Error", e); service.SetErrorState(e); throw; } catch (Exception e) { service.Logger.Error("Exception during process", e); replyMessage.AddMessage(new Message(new MessageError(e))); } } return replyMessage; }
private Message DoProcess(Message messageStream, int tryCount) { TcpConnection c = null; try { // Check if there's a connection in the pool already, c = connector.GetConnection(address); lock (c) { // Write the message. char code = '\0'; if (serviceType == ServiceType.Manager) { code = 'm'; } else if (serviceType == ServiceType.Root) { code = 'r'; } else if (serviceType == ServiceType.Block) { code = 'b'; } else if (serviceType == ServiceType.Admin) { code = 'a'; } BinaryWriter writer = new BinaryWriter(c.Stream, Encoding.Unicode); writer.Write(code); IMessageSerializer serializer = new BinaryRpcMessageSerializer(); serializer.Serialize(messageStream, c.Stream); writer.Flush(); Message response = serializer.Deserialize(c.Stream, MessageType.Response); if (response is MessageStream) { return response; } else { return new ResponseMessage((RequestMessage) messageStream, (ResponseMessage) response); } } } catch (Exception e) { // If this is a 'connection reset by peer' error, wipe the connection // from the cache and retry connection, if (tryCount == 0 && (e is SocketException || e is EndOfStreamException)) { connector.InvalidateConnection(address); // And retry, return DoProcess(messageStream, tryCount + 1); } MessageError error; if (e is EndOfStreamException) { error = new MessageError(new Exception("EOF (is net password correct?)", e)); } else { // Report this error as a msg_stream fault, error = new MessageError(new Exception(e.Message, e)); } Message responseMessage; if (messageStream is MessageStream) { responseMessage = new MessageStream(MessageType.Response); ResponseMessage inner = new ResponseMessage(); inner.Arguments.Add(error); ((MessageStream)responseMessage).AddMessage(inner); } else { responseMessage = ((RequestMessage) messageStream).CreateResponse(); responseMessage.Arguments.Add(error); } return responseMessage; } finally { if (c != null) connector.ReleaseConnection(c); } }
private void NotifyAllRootServersOfPost(PathInfo pathInfo, long uid, DataAddress rootNode) { // The root servers for the path, IServiceAddress[] roots = pathInfo.RootServers; // Create the message, MessageStream outputStream = new MessageStream(); outputStream.AddMessage(new Message("notifyNewProposal", pathInfo.PathName, uid, rootNode)); for (int i = 0; i < roots.Length; ++i) { IServiceAddress machine = roots[i]; // Don't notify this service, if (!machine.Equals(address)) { // If the service is up in the tracker, if (serviceTracker.IsServiceUp(machine, ServiceType.Root)) { // Send the message to the service, IMessageProcessor processor = connector.Connect(machine, ServiceType.Root); IEnumerable<Message> inputStream = processor.Process(outputStream); // If return is a connection fault, foreach (Message m in inputStream) { if (m.HasError && ReplicatedValueStore.IsConnectionFault(m)) { serviceTracker.ReportServiceDownClientReport(machine, ServiceType.Root); } } } } } }
private void PollServer(TrackedService server) { bool pollOk = true; string commandArg = null; if (server.ServiceType == ServiceType.Block) commandArg = "heartbeatB"; else if (server.ServiceType == ServiceType.Root) commandArg = "heartbeatR"; else if (server.ServiceType == ServiceType.Manager) commandArg = "heartbeatM"; else { tracker.log.Error(String.Format("Don't know how to poll type {0}", server.ServiceType)); pollOk = false; } // Send the poll command to the server, IMessageProcessor p = connector.Connect(server.ServiceAddress, ServiceType.Block); MessageStream outputStream = new MessageStream(); outputStream.AddMessage(new Message("poll", commandArg)); IEnumerable<Message> inputStream = p.Process(outputStream); foreach (Message m in inputStream) { // Any error with the poll means no status change, if (m.HasError) { pollOk = false; } } // If the poll is ok, set the status of the server to UP and remove from // the monitor list, if (pollOk) { // The server status is set to 'STATUS_UP' if either the current state // is 'DOWN CLIENT REPORT' or 'DOWN HEARTBEAT' // Synchronize over 'servers_map' for safe alteration of the ref. ServiceStatus oldStatus; lock (monitoredServers) { oldStatus = server.CurrentStatus; if (oldStatus == ServiceStatus.DownClientReport || oldStatus == ServiceStatus.DownHeartbeat) { server.CurrentStatus = ServiceStatus.Up; } // Remove the server from the monitored_servers list. monitoredServers.Remove(server); } if (tracker.log.IsInterestedIn(LogLevel.Information)) { tracker.log.Info(String.Format("Poll ok. Status now UP for {0} {1}", server.ServiceAddress, server.ServiceType)); } // Fire the event if the status changed, try { if (tracker.StatusChange != null) tracker.StatusChange(this, new ServiceStatusEventArgs(server.ServiceAddress, server.ServiceType, oldStatus, ServiceStatus.Up)); } catch (Exception e) { // Catch any exception generated. Log it but don't terminate the // thread. tracker.log.Error("Exception in listener during poll", e); } } else { // Make sure the server status is set to 'DOWN HEARTBEAT' if the poll // failed, // Synchronize over 'servers_map' for safe alteration of the ref. lock (monitoredServers) { ServiceStatus sts = server.CurrentStatus; if (sts == ServiceStatus.Up || sts == ServiceStatus.DownClientReport) { server.CurrentStatus = ServiceStatus.DownHeartbeat; } } } }
private bool SynchronizePathInfoData(PathAccess pathFile, IServiceAddress rootServer) { // Get the last entry, PathRecordEntry lastEntry = pathFile.GetLastEntry(); long uid; DataAddress daddr; if (lastEntry == null) { uid = 0; daddr = null; } else { uid = lastEntry.Uid; daddr = lastEntry.Address; } while (true) { // Fetch a bundle for the path from the root server, MessageStream outputStream = new MessageStream(); outputStream.AddMessage(new Message("internalFetchPathDataBundle", pathFile.PathName, uid, daddr)); // Send the command IMessageProcessor processor = connector.Connect(rootServer, ServiceType.Root); IEnumerable<Message> result = processor.Process(outputStream); long[] uids = null; DataAddress[] dataAddrs = null; foreach (Message m in result) { if (m.HasError) { // If it's a connection fault, report the error and return false if (ReplicatedValueStore.IsConnectionFault(m)) { serviceTracker.ReportServiceDownClientReport(rootServer, ServiceType.Root); return false; } throw new ApplicationException(m.ErrorMessage); } uids = (long[]) m.Arguments[0].Value; dataAddrs = (DataAddress[]) m.Arguments[1].Value; } // If it's empty, we reached the end so return, if (uids == null || uids.Length == 0) { break; } // Insert the data pathFile.AddPathDataEntries(uids, dataAddrs); // The last, uid = uids[uids.Length - 1]; daddr = dataAddrs[dataAddrs.Length - 1]; } return true; }
private void GetRegisteredBlockServers(MessageStream msg_out) { // Populate the list of registered block servers long[] guids; IServiceAddress[] srvs; lock (service.blockServersMap) { int sz = service.blockServersList.Count; guids = new long[sz]; srvs = new IServiceAddress[sz]; int i = 0; foreach (BlockServiceInfo m in service.blockServersList) { guids[i] = m.ServerGuid; srvs[i] = m.Address; ++i; } } // The reply message, msg_out.AddMessage(new Message(guids, srvs)); }
public IList<ITreeNode> FetchNodes(long[] nids) { // The number of nodes, int node_count = nids.Length; // The array of read nodes, ITreeNode[] result_nodes = new ITreeNode[node_count]; // Resolve special nodes first, { int i = 0; foreach (long nodeId in nids) { if ((nodeId & 0x01000000000000000L) != 0) result_nodes[i] = SparseLeafNode.Create(nodeId); ++i; } } // Group all the nodes to the same block, List<long> uniqueBlocks = new List<long>(); List<List<long>> uniqueBlockList = new List<List<long>>(); { int i = 0; foreach (long node_ref in nids) { // If it's not a special node, if ((node_ref & 0x01000000000000000L) == 0) { // Get the block id and add it to the list of unique blocks, DataAddress address = new DataAddress(node_ref); // Check if the node is in the local cache, ITreeNode node = networkCache.GetNode(address); if (node != null) { result_nodes[i] = node; } else { // Not in the local cache so we need to bundle this up in a node // request on the block servers, // Group this node request by the block identifier long blockId = address.BlockId; int ind = uniqueBlocks.IndexOf(blockId); if (ind == -1) { ind = uniqueBlocks.Count; uniqueBlocks.Add(blockId); uniqueBlockList.Add(new List<long>()); } List<long> blist = uniqueBlockList[ind]; blist.Add(node_ref); } } ++i; } } // Exit early if no blocks, if (uniqueBlocks.Count == 0) return result_nodes; // Resolve server records for the given block identifiers, IDictionary<long, IList<BlockServerElement>> servers_map = GetServersForBlock(uniqueBlocks); // The result nodes list, List<ITreeNode> nodes = new List<ITreeNode>(); // For each unique block list, foreach (List<long> blist in uniqueBlockList) { // Make a block server request for each node in the block, MessageStream block_server_msg = new MessageStream(MessageType.Request); long block_id = -1; foreach (long node_ref in blist) { DataAddress address = new DataAddress(node_ref); RequestMessage request = new RequestMessage("readFromBlock"); request.Arguments.Add(address); block_server_msg.AddMessage(request); block_id = address.BlockId; } if (block_id == -1) throw new ApplicationException("block_id == -1"); // Get the shuffled list of servers the block is stored on, IList<BlockServerElement> servers = servers_map[block_id]; // Go through the servers one at a time to fetch the block, bool success = false; for (int z = 0; z < servers.Count && !success; ++z) { BlockServerElement server = servers[z]; // If the server is up, if (server.IsStatusUp) { // Open a connection with the block server, IMessageProcessor block_server_proc = connector.Connect(server.Address, ServiceType.Block); MessageStream message_in = (MessageStream) block_server_proc.Process(block_server_msg); // DEBUG: ++networkCommCount; // DEBUG: ++networkFetchCommCount; bool is_error = false; bool severe_error = false; // Turn each none-error message into a node foreach (ResponseMessage m in message_in) { if (m.HasError) { // See if this error is a block read error. If it is, we don't // tell the manager server to lock this server out completely. bool is_block_read_error = m.Error.Source.Equals("Deveel.Data.Net.BlockReadException"); if (!is_block_read_error) { // If it's something other than a block read error, we mark // this error as severe, severe_error = true; } is_error = true; } else if (!is_error) { // The reply contains the block of data read. NodeSet node_set = (NodeSet)m.Arguments[0].Value; // Decode the node items into node objects, IEnumerator<Node> item_iterator = node_set.GetEnumerator(); while (item_iterator.MoveNext()) { // Get the node item, Node node_item = item_iterator.Current; long node_ref = node_item.Id; DataAddress address = new DataAddress(node_ref); // Wrap around a buffered DataInputStream for reading values // from the store. BinaryReader input = new BinaryReader(node_item.Input, Encoding.Unicode); short node_type = input.ReadInt16(); ITreeNode read_node; // Is the node type a leaf node? if (node_type == LeafType) { // Read the key int leaf_size = input.ReadInt32(); byte[] buf = ReadNodeAsBuffer(node_item); if (buf == null) { buf = new byte[leaf_size + 6]; input.Read(buf, 6, leaf_size); // Technically, we could comment these next two lines out. ByteBuffer.WriteInt2(node_type, buf, 0); ByteBuffer.WriteInt4(leaf_size, buf, 2); } // Create a leaf that's mapped to this data read_node = new ByteArrayTreeLeaf(node_ref, buf); ; } // Is the node type a branch node? else if (node_type == BranchType) { // Note that the entire branch is loaded into memory, int child_data_size = input.ReadInt32(); long[] data_arr = new long[child_data_size]; for (int n = 0; n < child_data_size; ++n) { data_arr[n] = input.ReadInt64(); } // Create the branch node, read_node = new TreeBranch(node_ref, data_arr, child_data_size); } else { throw new InvalidDataState("Unknown node type: " + node_type, address); } // Is the node already in the list? If so we don't add it. if (!IsInNodeList(node_ref, nodes)) { // Put the read node in the cache and add it to the 'nodes' // list. networkCache.SetNode(address, read_node); nodes.Add(read_node); } } } } // If there was no error while reading the result, we assume the node // requests were successfully read. if (is_error == false) { success = true; } else { if (severe_error) { // If this is an error, we need to report the failure to the // manager server, ReportBlockServerFailure(server.Address); // Remove the block id from the server list cache, networkCache.RemoveServers(block_id); } else { // Otherwise, not a severe error (probably a corrupt block on a // server), so shuffle the server list for this block_id so next // time there's less chance of hitting this bad block. IList<BlockServerElement> srvs = networkCache.GetServers(block_id); List<BlockServerElement> server_list = new List<BlockServerElement>(); server_list.AddRange(srvs); CollectionsUtil.Shuffle(server_list); networkCache.SetServers(block_id, server_list, 15 * 60 * 1000); } } } } // If the nodes were not successfully read, we generate an exception, if (!success) { // Remove from the cache, networkCache.RemoveServers(block_id); throw new ApplicationException("Unable to fetch node from block server"); } } int sz = nodes.Count; if (sz == 0) throw new ApplicationException("Empty nodes list"); for (int i = 0; i < sz; ++i) { ITreeNode node = nodes[i]; long node_ref = node.Id; for (int n = 0; n < nids.Length; ++n) { if (nids[n] == node_ref) result_nodes[n] = node; } } // Check the result_nodes list is completely populated, for (int n = 0; n < result_nodes.Length; ++n) { if (result_nodes[n] == null) throw new ApplicationException("Assertion failed: result_nodes not completely populated."); } return result_nodes; }
private void InternalFetchLogBundle(MessageStream replyMessage, long[] uid, bool initial) { // Perform this under a lock. This lock is also active for block queries // and administration updates. lock (blockDbWriteLock) { // Create a transaction ITransaction transaction = blockDatabase.CreateTransaction(); try { // Create the UIDList object, IDataFile uidListDf = transaction.GetFile(UidListKey, FileAccess.ReadWrite); UidList uidList = new UidList(uidListDf); // Go to the position of the uid, long pos = 0; if (uid != null) { pos = uidList.PositionOfUid(uid); } long end = Math.Min(pos + 32, uidList.Count); if (pos < 0) { pos = -(pos + 1); } // If initial is true, we go back a bit if (initial) { // Go back 16 entries in the log (but don't go back before the first) pos = Math.Max(0, (pos - 16)); } else { // Go to the next entry, pos = pos + 1; } // Send the bundle out to the stream, for (long i = pos; i < end; ++i) { long[] inUid = uidList.GetUid(i); byte[] buf = GetValueFromUid(transaction, inUid); replyMessage.AddMessage(new Message(inUid, buf)); } } finally { blockDatabase.Dispose(transaction); } } }
private IDictionary<long, IList<BlockServerElement>> GetServersForBlock(IList<long> blockIds) { // The result map, Dictionary<long, IList<BlockServerElement>> resultMap = new Dictionary<long, IList<BlockServerElement>>(); List<long> noneCached = new List<long>(blockIds.Count); foreach (long blockId in blockIds) { IList<BlockServerElement> v = networkCache.GetServers(blockId); // If it's cached (and the cache is current), if (v != null) { resultMap.Add(blockId, v); } // If not cached, add to the list of none cached entries, else { noneCached.Add(blockId); } } // If there are no 'none_cached' blocks, if (noneCached.Count == 0) // Return the result, return resultMap; // Otherwise, we query the manager server for current records on the given // blocks. IMessageProcessor manager = connector.Connect(managerAddress, ServiceType.Manager); MessageStream message_out = new MessageStream(MessageType.Request); foreach (long block_id in noneCached) { RequestMessage request = new RequestMessage("getServerListForBlock"); request.Arguments.Add(block_id); message_out.AddMessage(request); } MessageStream message_in = (MessageStream) manager.Process(message_out); int n = 0; foreach (ResponseMessage m in message_in) { if (m.HasError) throw new Exception(m.ErrorMessage, m.Error.AsException()); int sz = m.Arguments[0].ToInt32(); List<BlockServerElement> srvs = new List<BlockServerElement>(sz); IServiceAddress[] addresses = (IServiceAddress[]) m.Arguments[1].Value; int[] status = (int[]) m.Arguments[2].Value; for (int i = 0; i < sz; ++i) { srvs.Add(new BlockServerElement(addresses[i], (ServiceStatus) status[i])); } // Shuffle the list CollectionsUtil.Shuffle(srvs); // Move the server closest to this node to the start of the list, int closest = 0; int cur_close_factor = Int32.MaxValue; for (int i = 0; i < sz; ++i) { BlockServerElement elem = srvs[i]; int closeness_factor = GetProximity(elem.Address); if (closeness_factor < cur_close_factor) { cur_close_factor = closeness_factor; closest = i; } } // Swap if necessary, if (closest > 0) { CollectionsUtil.Swap(srvs, 0, closest); } // Put it in the result map, long block_id = noneCached[n]; resultMap.Add(block_id, srvs); // Add it to the cache, // NOTE: TTL hard-coded to 15 minute networkCache.SetServers(block_id, srvs, 15*60*1000); ++n; } // Return the list return resultMap; }
protected override IEnumerable<Message> Deserialize(BinaryReader reader) { int sz = reader.ReadInt32(); MessageStream stream = new MessageStream(); for (int i = 0; i < sz; i++) { stream.AddMessage(DeserializeMessage(reader)); } return stream; }
public MessageStream AsStream() { MessageStream stream = new MessageStream(); stream.AddMessage(this); return stream; }
public void AddMessageStream(IServiceAddress service_address, MessageStream message_stream, ServiceType message_type) { ServiceAddresses.Add(service_address); Messages.Add(message_stream); Types.Add(message_type); }