private MetaserverResponse ConnectToMetaserver(MetaRequest request) { int i = 0; while (true) { Console.WriteLine("ConnectToMetaserver: " + _lastMetaserver + " ..."); ServerId server = MetadataServerList[_lastMetaserver]; IMetaToClient serverInterface = (IMetaToClient)Activator.GetObject( typeof(IMetaToClient), "tcp://" + server.hostname + ":" + server.port + "/PADIConnection"); try { return(serverInterface.ClientProcessRequest(request)); } catch (SocketException) { Console.WriteLine("Server: " + server.id + " is not available"); _lastMetaserver = ((_lastMetaserver + 1) % 3); if (MAX_NUM_ATTEMPS == i++) { throw new Exception("Client: No metadataserver available"); } } } }
private static MetaserverResponse Close(MetaRequest request) { RequestClose closeRequest = (RequestClose)request; MetaserverResponse response; //Invocar o servidor try { Boolean success = core.Close(closeRequest.FileName, request.ClientId); if (success) { response = new MetaserverResponse(ResponseStatus.Success, request, ThisMetaserverId); } else { response = new MetaserverResponse(ResponseStatus.Exception, request, ThisMetaserverId); response.Exception = new PadiException(PadiExceptiontType.CloseFile, "File not closed"); } } catch (Exception ex) { response = new MetaserverResponse(ResponseStatus.Exception, request, ThisMetaserverId); response.Exception = new PadiException(PadiExceptiontType.CloseFile, ex.Message); } return(response); }
/// <summary> /// Receber o pedido do anterior, verificar se sou o serializer. Se sim, coloco o meu /// timestamp nisto. entrego à app e depois encaminho ao seguinte. Se sou o ultimo, /// </summary> /// <param name="request"></param> public void NewRequest(MetaRequest request) { //TODO Enviar um ack se ja conhecer este ficheiro ou nao (fazer o msg ack distinto) //SE JA CONHECE, Envia ao seguinte na mesma para que o seguinte trate disso. NewRequestDelegate del = new NewRequestDelegate(NewRequestProcess); del.Invoke(request); }
public MetaRequest SerializeRequest(MetaRequest request) { int namespaceId = GetNameSpaceID(request.FileName); long seqNumber = _namespaceParts[namespaceId].GetNewSeqNumber(); request.NamespaceSeqNumber = seqNumber; return(request); }
/// <summary> /// Tentar enviar ao seguinte. /// O seguinte é serializer, responde ao client. Envio ao seguinte /// </summary> private void SendToNext(MetaRequest request, MetaserverResponse result) { log.Debug(DateTime.Now.Ticks + " Send to Next: " + request); //Stamp as know by this server if (result != null) { request.KnownByThisServersList.Add(ThisMetaserverId); } //Check if this is the last server in view to know it int nextServer = ThisMetaserverId; //Se o seguinte falha, faço ack ao anterior, nao ha mais while (true) { Boolean iAmLast = false; nextServer = ViewManager.GetNextServerInView(nextServer, request.KnownByThisServersList, out iAmLast); if (iAmLast) { //Pode ser null, se o serializer estava indisponivel, vamos recalcular if (result == null) { Console.WriteLine("Initial serializer is not available"); request.Serializer = -1; NewRequestProcess(request); return; } //If I am last, reply to client and then ack back to others else: Debug.Assert(result != null); SendResponseToClient(result); Console.WriteLine("I am the last " + request); ReceiveResponse(result); return; } { try { //Tentar enviar ao seguinte //TODO Se ele responder que desconhece, fico à espera do ack. Se ao fim de x tempo nao receber, enviar outra vez log.Debug(DateTime.Now.Ticks + " [M] Message Sent: " + request.FileName); ConnectToMetaserver(nextServer).NewRequest(request); return; } catch (SocketException) { //Actualizar a view, esta mensagem tem de ser entregue mas a view tem de ser actualizada, Console.WriteLine("Next server fail"); ViewManager.ServerBetray(nextServer, ThisMetaserverId); } } } }
private static MetaserverResponse AppDelivery(MetaRequest request) { Console.WriteLine("App Delivery start:"); try { NamespaceManager.OperationAuth(request); } catch (PadiException e) { //Already processed // return null; } //Recebe os pedidos que ja estao prontos a entregar segundo o middleware //Invoke a nivel local //Após enviar o ack, vai carregar a próxima mensagem se existir //Processar o pedido, check type, unbox and process MetaserverResponse response; switch (request.RequestType) { case RequestType.Create: response = Create(request); break; case RequestType.Open: response = Open(request); break; case RequestType.Close: response = Close(request); break; case RequestType.Delete: response = Delete(request); break; case RequestType.Registry: response = Registry(request); break; case RequestType.Balancing: response = Balancing(request); break; default: response = new MetaserverResponse(ResponseStatus.InvalidRequest, request, ThisMetaserverId); break; } NamespaceManager.OperationDone(request); return(response); }
/** * Client Requests Retrival, process begins here: * Request stamp with localID+timestamp (Local Seq.Number) * Enqueue on this server * Deliver message to other view's servers * Ack client since other servers have this request, he can relax and wait. */ public MetaserverResponse ClientProcessRequest(MetaRequest request) { log.Debug(DateTime.Now.Ticks + " ClientProcessRequest: " + request); //if stop, enque this thread freezeNewRequests.WaitOne( ); Console.WriteLine("Passed"); //Stamp with local server ID request.SourceTimeStamp = "s-" + ThisMetaserverId + ":" + GetLocalTimeStamp(); //Ack client new NewRequestDelegate(NewRequestProcess).BeginInvoke(request, null, null); Console.WriteLine("Client process request"); return(new MetaserverResponse(ResponseStatus.Ack, request, ThisMetaserverId)); }
/// <summary> /// Corre numa thread independente /// </summary> /// <param name="request"></param> private void NewRequestProcess(MetaRequest request) { Console.WriteLine("New Request: " + request); log.Debug(DateTime.Now.Ticks + " New Request: " + request); //Get NamespaceId int namespaceId = NamespaceManager.GetNameSpaceID(request.FileName); //Get Serializer ID. if equal mine, get this sector next ID and stamp it int serializer = NamespaceManager.GetPartSerializer(namespaceId, ViewManager); //A mensagem nao tem serializador mas sou eu: entao serializo if (request.Serializer == -1) { if (serializer == ThisMetaserverId) { //sou eu a serializar isto request.Serializer = ThisMetaserverId; //Se os servidores querem congelar, nao vou lancar mais pedidos. //Se nao serializar nem aceitar novos pedidos, o sistema fica isolado freezeNewRequests.WaitOne( ); Console.WriteLine("Passed Serializer"); log.Debug(DateTime.Now.Ticks + " Start Serializing request: " + request); request = NamespaceManager.SerializeRequest(request); log.Debug(DateTime.Now.Ticks + " Request serialized: " + request); } else { //passo a outro para ele serializar isto e espero que volte SendToNext(request, null); return; } } //agora tem serializador de certeza if (request.Serializer != serializer) { //Discordo quem seja o serializador Console.WriteLine("Dont agree: " + request.Serializer + " is the serializer. Should be: " + serializer); } //Concordo com o serializador, entregar Console.WriteLine("Deliver to App " + request); //Deliver to app (if this request is newer (serializer tells it)) MetaserverResponse result = AppDelivery(request); SendToNext(request, result); }
/// <summary> /// Send the request to metaserver, lock until response. If timeout, repeat request /// </summary> /// <param name="request"></param> /// <returns></returns> public MetaserverResponse SendRequestToMetaserver(MetaRequest request) { //Fill the request source details: int requestId = GetNewRequestId( ); request.ClientHostname = ClientHostname; request.ClientReqStamp = "c:" + ClientId + ":" + ClientHostname + ":" + ClientPort + ":" + requestId; request.ClientPort = ClientPort; request.ClientId = ClientId; EventWaitHandle monitor = new EventWaitHandle(false, EventResetMode.AutoReset, "Client" + request.ClientReqStamp); MetaserverResponse response = null; while (true) { request.Attempt++; //Do remote sync request response = ConnectToMetaserver(request); //Pedido foi entregue ao master //Wait no monitor com o ID do pedido ate receber a resposta monitor.WaitOne(MetaServerResponseTimeout, true); //Este wait tem timeout e é desempedido a quando da resposta dos meta lock ( ResponseList ) { if (ResponseList.TryGetValue(request.ClientReqStamp, out response)) { if (response != null) { break; } } } //Se a resposta nao veio, vamos realizar repeticao de pedido } if (response.Status.Equals(ResponseStatus.Exception)) { PadiException exception = response.Exception; throw exception; } return(response); }
private static MetaserverResponse Registry(MetaRequest request) { RequestRegistry registryRequest = (RequestRegistry)request; MetaserverResponse response; try { core.Registry(registryRequest.ServerId, registryRequest.ServerIp, registryRequest.ServerPort); response = new MetaserverResponse(ResponseStatus.Success, request, ThisMetaserverId); } catch (Exception ex) { response = new MetaserverResponse(ResponseStatus.Exception, request, ThisMetaserverId); response.Exception = new PadiException(PadiExceptiontType.Registry, ex.Message); } return(response); }
private static MetaserverResponse Open(MetaRequest request) { RequestOpen openRequest = (RequestOpen)request; MetaserverResponse response; try { MetadataEntry entry = core.Open(openRequest.FileName, request.ClientId); response = new MetaserverResponse(ResponseStatus.Success, request, ThisMetaserverId); response.MetaEntry = entry; } catch (Exception ex) { response = new MetaserverResponse(ResponseStatus.Exception, request, ThisMetaserverId); response.Exception = new PadiException(PadiExceptiontType.OpenFile, ex.Message); } return(response); }
private static MetaserverResponse Create(MetaRequest request) { RequestCreate createRequest = (RequestCreate)request; MetaserverResponse response; //Invoca o servidor try { MetadataEntry entry = core.Create(createRequest.FileName, createRequest.NbDataServer, createRequest.ReadQuorum, createRequest.WriteQuorum, request.ClientId); response = new MetaserverResponse(ResponseStatus.Success, request, ThisMetaserverId); response.MetaEntry = entry; } catch (Exception ex) { response = new MetaserverResponse(ResponseStatus.Exception, request, ThisMetaserverId); response.Exception = new PadiException(PadiExceptiontType.CreateFile, ex.Message); } return(response); }
private static MetaserverResponse Balancing(MetaRequest request) { Console.WriteLine("New balancing message"); if (!LoadBalancer.Enabled) { Console.WriteLine("Load balance not enable"); return(new MetaserverResponse(ResponseStatus.Success, request, ThisMetaserverId)); } Console.WriteLine("Load balance enable"); RequestBalancing balancingRequest = (RequestBalancing)request; MetaserverResponse response; try { core.Balancing(balancingRequest); response = new MetaserverResponse(ResponseStatus.Success, request, ThisMetaserverId); } catch (Exception ex) { response = new MetaserverResponse(ResponseStatus.Exception, request, ThisMetaserverId); response.Exception = new PadiException(PadiExceptiontType.Balancing, ex.Message); } return(response); }
public void OperationAuth(MetaRequest request) { int namespaceId = GetNameSpaceID(request.FileName); _namespaceParts[namespaceId].OperationAuth(request.FileName, request.NamespaceSeqNumber); }
public void OperationDone(MetaRequest request) { int namespaceId = GetNameSpaceID(request.FileName); _namespaceParts[namespaceId].AllowNext(request.FileName, request.NamespaceSeqNumber); }