Пример #1
0
        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");
                    }
                }
            }
        }
Пример #2
0
        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);
        }
Пример #3
0
        /// <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);
        }
Пример #4
0
        public MetaRequest SerializeRequest(MetaRequest request)
        {
            int  namespaceId = GetNameSpaceID(request.FileName);
            long seqNumber   = _namespaceParts[namespaceId].GetNewSeqNumber();

            request.NamespaceSeqNumber = seqNumber;
            return(request);
        }
Пример #5
0
        /// <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);
                    }
                }
            }
        }
Пример #6
0
        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);
        }
Пример #7
0
        /**
         * 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));
        }
Пример #8
0
        /// <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);
        }
Пример #9
0
        /// <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);
        }
Пример #10
0
        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);
        }
Пример #11
0
        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);
        }
Пример #12
0
        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);
        }
Пример #13
0
        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);
        }
Пример #14
0
        public void OperationAuth(MetaRequest request)
        {
            int namespaceId = GetNameSpaceID(request.FileName);

            _namespaceParts[namespaceId].OperationAuth(request.FileName, request.NamespaceSeqNumber);
        }
Пример #15
0
        public void OperationDone(MetaRequest request)
        {
            int namespaceId = GetNameSpaceID(request.FileName);

            _namespaceParts[namespaceId].AllowNext(request.FileName, request.NamespaceSeqNumber);
        }