Beispiel #1
0
        // PercentageStat is a basic stat plus percent calc
        public override OSDMap ToOSDMap()
        {
            // Get the foundational instance
            OSDMap map = base.ToOSDMap();

            map["StatType"] = "PercentageStat";

            map.Add("Antecedent", OSD.FromLong(Antecedent));
            map.Add("Consequent", OSD.FromLong(Consequent));

            return(map);
        }
 // Get a copy of the current histogram
 public OSDArray GetHistogramAsOSDArray()
 {
     OSDArray ret = new OSDArray(m_numBuckets);
     lock (histoLock)
     {
         int indx = m_lastBucket + 1;
         for (int ii = 0; ii < m_numBuckets; ii++, indx++)
         {
             if (indx >= m_numBuckets)
                 indx = 0;
             ret[ii] = OSD.FromLong(m_histogram[indx]);
         }
     }
     return ret;
 }
Beispiel #3
0
        public override OSDMap OReport(string uptime, string version)
        {
            double elapsedHours = (DateTime.Now - startTime).TotalHours;

            if (elapsedHours <= 0)
            {
                elapsedHours = 1;
            }                                             // prevent divide by zero

            long assetRequestsTodayPerHour     = (long)Math.Round(AssetRequestsToday / elapsedHours);
            long assetRequestsYesterdayPerHour = (long)Math.Round(AssetRequestsYesterday / 24.0);

            OSDMap ret = new OSDMap();

            ret.Add("AssetRequestsToday", OSD.FromLong(AssetRequestsToday));
            ret.Add("AssetRequestsTodayPerHour", OSD.FromLong(assetRequestsTodayPerHour));
            ret.Add("AssetRequestsNotFoundToday", OSD.FromLong(AssetRequestsNotFoundToday));
            ret.Add("AssetRequestsYesterday", OSD.FromLong(AssetRequestsYesterday));
            ret.Add("AssetRequestsYesterdayPerHour", OSD.FromLong(assetRequestsYesterdayPerHour));
            ret.Add("AssetRequestsNotFoundYesterday", OSD.FromLong(assetRequestsNotFoundYesterday));

            return(ret);
        }
        /// <summary>
        /// Handles a quark crossing request. Checks to see if the request is possible, and returns true or false based on
        /// the validity of the crossing to the actor who requested. This is performed in 3 steps:
        /// Step 1: Tell root to be ready to receive crossing requests for the object
        /// Root will also do sanity checks (e.g. object was deleted before crossing), so checking actorStatus code
        /// is important.
        /// Step 2: Root provides URL for uploading updated properties and for downloading said object.
        /// Step 3: Tell actor about the URL where it may contact the root directly.
        /// TODO: This can be optimized if we are allowed to remember or calculate the URL. We could respond immediately with the URL
        /// and the actor would keep trying it until root accepts it. For now, we avoid concurrency.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="actorRequest"></param>
        private void HandleCrossing(HttpListenerContext context, HttpListenerRequest actorRequest)
        {
            StreamReader    actorReader = new StreamReader(actorRequest.InputStream);
            XmlSerializer   deserializer = new XmlSerializer(typeof(CrossingRequest));
            CrossingRequest cross = (CrossingRequest)deserializer.Deserialize(actorReader);
            QuarkPublisher  curQp = null, prevQp = null;
            string          url = "";
            HttpStatusCode  status;

            m_crossLock.EnterReadLock();
            try
            {
                m_log.InfoFormat("{0}: Handling Crossing. Time: {1}", LogHeader, DateTime.Now.Ticks);
                if (m_quarkSubscriptions.TryGetValue(cross.curQuark, out curQp) && m_quarkSubscriptions.TryGetValue(cross.prevQuark, out prevQp))
                {
                    if (curQp.RootActorID != prevQp.RootActorID)
                    {
                        // TODO: Inter-root communication
                    }
                    else
                    {
                        // Actor's response variables
                        HttpListenerResponse actorResponse = context.Response;
                        Stream actorOutput = actorResponse.OutputStream;

                        // Root's request variables
                        RootInfo       root        = (RootInfo)m_actor[curQp.RootActorID];
                        HttpWebRequest rootRequest = (HttpWebRequest)WebRequest.Create("http://" + root.quarkAddress + "/cross/");
                        rootRequest.Credentials = CredentialCache.DefaultCredentials;
                        rootRequest.Method      = "POST";
                        rootRequest.ContentType = "text/json";
                        Stream rootOutput = rootRequest.GetRequestStream();

                        status = ValidateCrossing(cross);
                        if (status != HttpStatusCode.Created)
                        {
                            actorResponse.StatusCode = (int)status;
                            actorOutput.Close();
                            actorResponse.Close();
                            return;
                        }
                        // From here on, I might have to write, make sure we only do one of these at a time.
                        // Can't go in UpgradeableLock with a ReadLock, so let go first.
                        m_crossLock.ExitReadLock();
                        m_crossLock.EnterUpgradeableReadLock();
                        try
                        {
                            // First we double check nothing changed while we were waiting for the lock, and we are still valid to cross.
                            status = ValidateCrossing(cross);
                            if (status != HttpStatusCode.Created)
                            {
                                actorResponse.StatusCode = (int)status;
                                actorOutput.Close();
                                actorResponse.Close();
                                return;
                            }

                            // Step 1: Tell root to be ready to receive crossing requests for the object
                            // Root will also do sanity checks (e.g. object was deleted before crossing), so checking actorStatus code
                            // is important.
                            OSDMap DataMap = new OSDMap();
                            DataMap["uuid"] = OSD.FromUUID(cross.uuid);
                            DataMap["pq"]   = OSD.FromString(cross.prevQuark);
                            DataMap["cq"]   = OSD.FromString(cross.curQuark);
                            DataMap["ts"]   = OSD.FromLong(cross.timestamp);

                            string encodedMap     = OSDParser.SerializeJsonString(DataMap, true);
                            byte[] rootData       = System.Text.Encoding.ASCII.GetBytes(encodedMap);
                            int    rootDataLength = rootData.Length;
                            rootOutput.Write(rootData, 0, rootDataLength);
                            rootOutput.Close();

                            // Step 2: Root provides URL for uploading updated properties and for downloading said object.
                            HttpWebResponse response = (HttpWebResponse)rootRequest.GetResponse();
                            if (HttpStatusCode.OK == response.StatusCode)
                            {
                                m_crossLock.EnterWriteLock();
                                try
                                {
                                    m_crossings[cross.uuid]       = new CurrentCrossings();
                                    m_crossings[cross.uuid].cross = cross;
                                    m_crossings[cross.uuid].actors.UnionWith(m_quarkSubscriptions[cross.prevQuark].GetAllQuarkSubscribers());
                                    m_crossings[cross.uuid].actors.UnionWith(m_quarkSubscriptions[cross.curQuark].GetAllQuarkSubscribers());
                                    // Remove the starting actor from the list of actors to ACK.
                                    m_crossings[cross.uuid].actors.Remove(cross.actorID);
                                    m_crossings[cross.uuid].rootHandler = root;
                                }
                                finally
                                {
                                    m_crossLock.ExitWriteLock();
                                }
                                Stream       respData   = response.GetResponseStream();
                                StreamReader rootReader = new StreamReader(respData);
                                url = rootReader.ReadToEnd();
                                m_log.WarnFormat("{0}: Got URL for object request from server: {1}", LogHeader, url);
                                if (url.Length > 0)
                                {
                                    // Step 3: Tell actor about the URL where it may contact the root directly.
                                    // TODO: This can be optimized if we are allowed to remember or calculate the URL. We could respond immediately with the URL
                                    // and the actor would keep trying it until root accepts it. For now, we avoid concurrency.
                                    actorResponse.StatusCode = (int)HttpStatusCode.Created;
                                    byte[] actorUrlData       = System.Text.Encoding.ASCII.GetBytes(url);
                                    int    actorUrlDataLength = actorUrlData.Length;
                                    actorOutput.Write(actorUrlData, 0, actorUrlDataLength);
                                    actorOutput.Close();
                                    actorResponse.Close();
                                }
                                else
                                {
                                    m_log.ErrorFormat("{0}: Received empty URL from Root", LogHeader);
                                }
                            }
                            else
                            {
                                m_log.ErrorFormat("{0}: Failed to request crossing from root. Error Code: {1}", LogHeader, response.StatusCode);
                            }
                        }
                        finally
                        {
                            m_crossLock.ExitUpgradeableReadLock();
                        }
                    }
                }
            }
            catch (Exception e)
            {
                m_log.ErrorFormat("{0}: Failed to request crossing from root and forward to actor. Exception: {1}\n{2}", LogHeader, e, e.StackTrace);
            }
            finally
            {
                if (m_crossLock.IsReadLockHeld)
                {
                    m_crossLock.ExitReadLock();
                }
            }
        }
        /// <summary>
        /// Used for actors ACKing received crossed messages. Once all expected actors have ACKEd the crossing message,
        /// the Sync Service informs the root actor to push a crossing finished.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="request"></param>
        private void HandleAckCrossing(HttpListenerContext context, HttpListenerRequest request)
        {
            m_log.InfoFormat("{0}: HandleAckCrossing", LogHeader);
            StreamReader     actorReader  = new StreamReader(request.InputStream);
            XmlSerializer    deserializer = new XmlSerializer(typeof(CrossingFinished));
            CrossingFinished cf           = (CrossingFinished)deserializer.Deserialize(actorReader);
            string           ackActorID   = cf.ackActorID;
            CrossingRequest  cross        = cf.cross;
            RootInfo         root         = null;

            bool allAcksReceived = false;

            try
            {
                HttpStatusCode actorStatus;
                m_crossings[cross.uuid].actors.Remove(ackActorID);
                m_log.InfoFormat("{0}: Ack received from {1}, {2} acks remaining.", LogHeader, ackActorID, m_crossings[cross.uuid].actors.Count);
                if (m_crossings[cross.uuid].actors.Count == 0)
                {
                    root            = m_crossings[cross.uuid].rootHandler;
                    actorStatus     = CancelCrossing(cross);
                    allAcksReceived = true;
                }
                else
                {
                    actorStatus = HttpStatusCode.OK;
                }

                HttpListenerResponse actorResponse = context.Response;
                actorResponse.StatusCode = (int)actorStatus;
                actorResponse.Close();

                if (allAcksReceived)
                {
                    if (actorStatus == HttpStatusCode.OK)
                    {
                        m_log.InfoFormat("{0}: Informing root that crossing is finished", LogHeader);
                        // Now tell root to tell every actor that the crossing is finnished!
                        // Root's request variables
                        HttpWebRequest rootRequest = (HttpWebRequest)WebRequest.Create("http://" + root.quarkAddress + "/finished/");
                        rootRequest.Credentials = CredentialCache.DefaultCredentials;
                        rootRequest.Method      = "POST";
                        rootRequest.ContentType = "text/json";
                        Stream rootOutput = rootRequest.GetRequestStream();

                        OSDMap DataMap = new OSDMap();
                        DataMap["uuid"] = OSD.FromUUID(cross.uuid);
                        DataMap["ts"]   = OSD.FromLong(cross.timestamp);

                        string encodedMap     = OSDParser.SerializeJsonString(DataMap, true);
                        byte[] rootData       = System.Text.Encoding.ASCII.GetBytes(encodedMap);
                        int    rootDataLength = rootData.Length;
                        rootOutput.Write(rootData, 0, rootDataLength);
                        rootOutput.Close();

                        // Check if everything went OK
                        try
                        {
                            HttpWebResponse response = (HttpWebResponse)rootRequest.GetResponse();
                            if (response.StatusCode == HttpStatusCode.OK)
                            {
                                m_log.InfoFormat("{0}: Successfully finished crossing.", LogHeader);
                                return;
                            }
                        }
                        catch (WebException we)
                        {
                            var resp = we.Response as HttpWebResponse;
                            m_log.ErrorFormat("{0}: Sync Crossing finished fail with actorStatus code: {1}", LogHeader, resp.StatusCode);
                        }
                    }
                    else
                    {
                        throw new Exception("Could not find the object in the crossing dictionary");
                    }
                }
            }
            catch (Exception e)
            {
                m_log.ErrorFormat("{0}: Unkown exception while handling ACK from actor. Exception {1}", LogHeader, e);
            }
        }
Beispiel #6
0
        /// <summary>
        /// Convert the value of the given property to OSD type.
        /// </summary>
        /// <param name="property"></param>
        /// <returns></returns>
        public OSDArray ToOSDArray()
        {
            //DebugLog.WarnFormat("[SYNCED PROPERTY] ToOSDArray called for property {0}", Property.ToString());
            lock (m_lock)
            {
                OSDArray propertyData = new OSDArray();
                propertyData.Add(OSD.FromInteger((uint)Property));
                propertyData.Add(OSD.FromLong(LastUpdateTimeStamp));
                propertyData.Add(OSD.FromString(LastUpdateSyncID));

                OSD value = null;
                switch (Property)
                {
                ///////////////////////////////////////
                //SOP properties with complex structure
                ///////////////////////////////////////
                case SyncableProperties.Type.AgentCircuitData:
                case SyncableProperties.Type.AvatarAppearance:
                    value = (OSDMap)LastUpdateValue;
                    break;

                case SyncableProperties.Type.Animations:
                    value = (OSDArray)LastUpdateValue;
                    break;

                ////////////////////////////
                // Integer/enum type properties
                ////////////////////////////
                case SyncableProperties.Type.CreationDate:              // int
                case SyncableProperties.Type.LinkNum:                   // int
                case SyncableProperties.Type.OwnershipCost:             // int
                case SyncableProperties.Type.SalePrice:                 // int
                case SyncableProperties.Type.ScriptAccessPin:           // int
                case SyncableProperties.Type.AggregateScriptEvents:     // enum
                case SyncableProperties.Type.Flags:                     // enum
                case SyncableProperties.Type.LocalFlags:                // enum
                case SyncableProperties.Type.PresenceType:              // enum
                    value = OSD.FromInteger((int)LastUpdateValue);
                    break;

                ////////////////////////////
                // Byte type properties
                ////////////////////////////
                case SyncableProperties.Type.ClickAction:
                case SyncableProperties.Type.Material:
                case SyncableProperties.Type.ObjectSaleType:
                    value = OSD.FromInteger((byte)LastUpdateValue);
                    break;

                ////////////////////////////
                // Boolean type properties
                ////////////////////////////
                case SyncableProperties.Type.AllowedDrop:
                case SyncableProperties.Type.IsAttachment:
                case SyncableProperties.Type.PassTouches:
                case SyncableProperties.Type.VolumeDetectActive:
                case SyncableProperties.Type.Flying:
                case SyncableProperties.Type.IsColliding:
                case SyncableProperties.Type.CollidingGround:
                case SyncableProperties.Type.Kinematic:
                case SyncableProperties.Type.IsSelected:
                case SyncableProperties.Type.AllowMovement:
                    value = OSD.FromBoolean((bool)LastUpdateValue);
                    break;

                ////////////////////////////
                // Vector3 type properties
                ////////////////////////////
                case SyncableProperties.Type.AngularVelocity:
                case SyncableProperties.Type.AttachedPos:
                case SyncableProperties.Type.GroupPosition:
                case SyncableProperties.Type.OffsetPosition:
                case SyncableProperties.Type.Scale:
                case SyncableProperties.Type.SitTargetPosition:
                case SyncableProperties.Type.SitTargetPositionLL:
                case SyncableProperties.Type.SOP_Acceleration:
                case SyncableProperties.Type.Velocity:
                case SyncableProperties.Type.Force:
                case SyncableProperties.Type.PA_Acceleration:
                case SyncableProperties.Type.PA_Velocity:
                case SyncableProperties.Type.PA_TargetVelocity:
                case SyncableProperties.Type.Position:
                case SyncableProperties.Type.RotationalVelocity:
                case SyncableProperties.Type.Size:
                case SyncableProperties.Type.Torque:
                case SyncableProperties.Type.AbsolutePosition:
                    value = OSD.FromVector3((Vector3)LastUpdateValue);
                    break;

                ////////////////////////////
                // UUID type properties
                ////////////////////////////
                case SyncableProperties.Type.AttachedAvatar:
                case SyncableProperties.Type.CollisionSound:
                case SyncableProperties.Type.CreatorID:
                case SyncableProperties.Type.FolderID:
                case SyncableProperties.Type.GroupID:
                case SyncableProperties.Type.LastOwnerID:
                case SyncableProperties.Type.OwnerID:
                case SyncableProperties.Type.Sound:
                    value = OSD.FromUUID((UUID)LastUpdateValue);
                    break;

                ////////////////////////////
                // UInt type properties
                ////////////////////////////
                case SyncableProperties.Type.LocalId:
                case SyncableProperties.Type.AttachmentPoint:
                case SyncableProperties.Type.BaseMask:
                case SyncableProperties.Type.Category:
                case SyncableProperties.Type.EveryoneMask:
                case SyncableProperties.Type.GroupMask:
                case SyncableProperties.Type.InventorySerial:
                case SyncableProperties.Type.NextOwnerMask:
                case SyncableProperties.Type.OwnerMask:
                case SyncableProperties.Type.AgentControlFlags:
                case SyncableProperties.Type.ParentId:
                    value = OSD.FromUInteger((uint)LastUpdateValue);
                    break;

                ////////////////////////////
                // Float type properties
                ////////////////////////////
                case SyncableProperties.Type.CollisionSoundVolume:
                case SyncableProperties.Type.Buoyancy:
                    value = OSD.FromReal((float)LastUpdateValue);
                    break;

                ////////////////////////////
                // String type properties
                ////////////////////////////
                case SyncableProperties.Type.Color:
                case SyncableProperties.Type.CreatorData:
                case SyncableProperties.Type.Description:
                case SyncableProperties.Type.MediaUrl:
                case SyncableProperties.Type.Name:
                case SyncableProperties.Type.RealRegion:
                case SyncableProperties.Type.Shape:
                case SyncableProperties.Type.SitName:
                case SyncableProperties.Type.TaskInventory:
                case SyncableProperties.Type.Text:
                case SyncableProperties.Type.TouchName:
                    value = OSD.FromString((string)LastUpdateValue);
                    break;

                ////////////////////////////
                // byte[] (binary data) type properties
                ////////////////////////////
                case SyncableProperties.Type.ParticleSystem:
                case SyncableProperties.Type.TextureAnimation:
                    value = OSD.FromBinary((byte[])LastUpdateValue);
                    break;

                ////////////////////////////
                // Quaternion type properties
                ////////////////////////////
                case SyncableProperties.Type.RotationOffset:
                case SyncableProperties.Type.SitTargetOrientation:
                case SyncableProperties.Type.SitTargetOrientationLL:
                case SyncableProperties.Type.Orientation:
                case SyncableProperties.Type.Rotation:
                    value = OSD.FromQuaternion((Quaternion)LastUpdateValue);
                    break;

                default:
                    DebugLog.WarnFormat("[SYNCED PROPERTY] ToOSDArray: No handler for property {0} ", Property);
                    break;
                }
                propertyData.Add(value);
                return(propertyData);
            }
        }