Пример #1
0
        /// <summary>
        /// Selects the servers to use for strong consistency reads.
        /// This always returns the primary, though, in some cases, it may be possible to
        /// determine whether a secondary replica is sufficiently up-to-date.
        /// </summary>
        /// <param name="objectName">The object being read</param>
        /// <returns>The selected servers.</returns>
        public HashSet <ServerState> SelectServersForStrongConsistency(string objectName)
        {
            HashSet <ServerState> set = new HashSet <ServerState>();

            foreach (string server in config.PrimaryServers)
            {
                if (!config.WriteOnlyPrimaryServers.Contains(server))
                {
                    set.Add(monitor.GetServerState(server));
                }
            }
            return(set);
        }
Пример #2
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);
        }
Пример #3
0
        private void FastWrite(WriteOp op, List <SessionState> sessions = null, ServerMonitor monitor = null)
        {
            // there should only be one primary server since we are in fast mode
            string     server = configuration.PrimaryServers.First();
            ICloudBlob blob   = ClientRegistry.GetCloudBlob(server, configuration.Name, blobName, false);

            watch.Start();
            op(blob);
            watch.Stop();

            // update server and session 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);
                }
            }
        }