Exemple #1
0
        private void MultiWrite(WriteOp op, AccessCondition access, List <SessionState> sessions = null, ServerMonitor monitor = null)
        {
            // This protocol uses three phases and ETags
            // It assumes that the client is in fast mode and remains so throughout the protocol
            // i.e. it assumes that the set of primaries does not change.
            // TODO: recover from failed clients that may leave a write partially completed

            ICloudBlob blob;
            Dictionary <string, string> eTags;

            // Phase 1.  Mark intention to write with write-in-progress flags
            eTags = SetWiPFlags();
            if (eTags == null)
            {
                // flags were not successfully set, so abort the protocol
                return;
            }

            // Phase 2.  Perform write at all primaries
            bool didAtLeastOne = false;

            foreach (string server in configuration.PrimaryServers)
            {
                blob = ClientRegistry.GetCloudBlob(server, configuration.Name, blobName, false);
                access.IfMatchETag = eTags[server];
                watch.Start();
                try
                {
                    op(blob);
                }
                catch (StorageException)
                {
                    // If writing fails at some primary, then abort the protocol
                    // It could be that a concurrent writer is in progress
                    // Note that some writes may have already been performed
                    // If so, then we leave the WiP flags set so the recovery process will kick in
                    // or so a concurrent writer can complete its protocol and overwrite our writes
                    // If not, then we can clear the WiP flags
                    if (!didAtLeastOne)
                    {
                        ClearWiPFlags(eTags);
                    }
                    return;
                }
                watch.Stop();
                eTags[server] = blob.Properties.ETag;
                didAtLeastOne = true;

                // update session and server state
                ServerState ss = (monitor == null) ? slaEngine.Monitor.GetServerState(server) : monitor.GetServerState(server);
                ss.AddRtt(watch.ElapsedMilliseconds);
                if (sessions == null)
                {
                    slaEngine.Session.RecordObjectWritten(blobName, Timestamp(blob), ss);
                }
                else
                {
                    foreach (SessionState session in sessions)
                    {
                        session.RecordObjectWritten(blobName, Timestamp(blob), ss);
                    }
                }
            }

            // Phase 3.  Clear write-in-progress flags to indicate that write has completed
            ClearWiPFlags(eTags);
        }
Exemple #2
0
        private void SlowWrite(WriteOp op, AccessCondition accessCondition, List <SessionState> sessions = null, ServerMonitor monitor = null)
        {
            // A reconfiguration is in progress, but may not have happened yet.
            // We could try to complete this write before the reconfiguration, but that would require locking
            // to prevent the configuration service from changing the configuration during this write.
            // Instead, we take the simple approach of waiting for the reconfiguration to complete.

            bool isDone = false;

            do  // while unable to lease the configuration
            {
                if (configuration.IsInFastMode(renew: true))
                {
                    if (configuration.PrimaryServers.Count == 1)
                    {
                        FastWrite(op, sessions, monitor);
                    }
                    else
                    {
                        MultiWrite(op, accessCondition, sessions, monitor);
                    }
                    isDone = true;
                }
                else
                {
                    Thread.Sleep(ConstPool.CONFIGURATION_ACTION_DURATION);
                }
            }while (!isDone);
        }
Exemple #3
0
        public ConsistencySLAEngine(ServiceLevelAgreement sla, ReplicaConfiguration config, SessionState sessionState = null, ServerMonitor monitor = null, ChosenUtility chosenUtility = null)
        {
            this.Sla    = sla;
            this.Config = config;

            if (sessionState != null)
            {
                this.Session = sessionState;
            }
            else
            {
                this.Session = new SessionState();
            }

            if (monitor != null)
            {
                this.Monitor = monitor;
            }
            else
            {
                this.Monitor = new ServerMonitor(config);
            }

            this.chosenUtility = chosenUtility;
            this.selector      = new ServerSelector(Session, Config, Monitor);
        }
Exemple #4
0
 public void Write(WriteOp op, AccessCondition accessCondition, List <SessionState> sessions = null, ServerMonitor monitor = null)
 {
     // TODO: ensure that there is enough time left on the lease to complete the write
     // Can set a timeout using BlobRequestOptions and/or renew a least that is about to expire
     if (configuration.IsInFastMode())
     {
         if (configuration.PrimaryServers.Count == 1)
         {
             FastWrite(op, sessions, monitor);
         }
         else
         {
             MultiWrite(op, accessCondition, sessions, monitor);
         }
     }
     else
     {
         SlowWrite(op, accessCondition, sessions, monitor);
     }
 }
Exemple #5
0
 /// <summary>
 /// Constructs a new server selector instance.
 /// </summary>
 /// <param name="session">holds the session state</param>
 /// <param name="config">holds the current replica configuration</param>
 public ServerSelector(SessionState session, ReplicaConfiguration config, ServerMonitor monitor)
 {
     this.session = session;
     this.config  = config;
     this.monitor = monitor;
 }