public IObjectChange <Usuario> ObjectChange() { var o = new ObjectChange(); o.PropertyChanges = new List <PropertyChange>(); return(o); }
/// <summary> /// For performance reasons, we ignore some events. These are: /// 1. The heartbeat event from xapi, which is a "change" on the pool object, but where the object doesn't actually change. /// 2. Tasks that are frequent and which we don't care about, like SR.scan. /// 3. Changes on SR that only toggle current_operations. These happen at the same time as the /// periodic SR.scan. /// </summary> private bool IgnoreObjectChange(ObjectChange obj) { if (obj.value == null) { // Object is being deleted. Never ignore these! return(false); } else if (obj.type == typeof(Task)) { Task task = (Task)obj.value; return(task.IgnoreInCacheUpdate()); } else if (obj.type == typeof(Pool)) { Pool newPool = (Pool)obj.value; Pool oldPool = Resolve(new XenRef <Pool>(obj.xenref)); return(oldPool != null && newPool.DeepEquals(oldPool, false)); //We do want to see changes in the Pool.current_operations. } else if (obj.type == typeof(SR)) { SR newSR = (SR)obj.value; SR oldSR = Resolve(new XenRef <SR>(obj.xenref)); return(oldSR != null && newSR.DeepEquals(oldSR, true)); } else { return(false); } }
/// <summary> /// Sends an ObjectChanged message to a customer. /// </summary> /// <param name="requestUuid">The request UUID.</param> /// <param name="change">The object change.</param> /// <param name="isFinalPart">Whether or not this is the final part of a multi-part message.</param> /// <param name="extension">The message header extension.</param> /// <returns>The sent message on success; <c>null</c> otherwise.</returns> public virtual EtpMessage <ObjectChanged> ObjectChanged(Guid requestUuid, ObjectChange change, bool isFinalPart = true, IMessageHeaderExtension extension = null) { var body = new ObjectChanged { RequestUuid = requestUuid, Change = change, }; return(SendNotification(body, extension: extension, isMultiPart: true, isFinalPart: isFinalPart)); }
/// <summary> /// Sends an ObjectChanged message to a customer. /// </summary> /// <param name="request">The request.</param> /// <param name="change">The object change.</param> /// <returns>The message identifier.</returns> public long ObjectChanged(IMessageHeader request, ObjectChange change) { var header = CreateMessageHeader(Protocols.StoreNotification, MessageTypes.StoreNotification.ObjectChanged, request.MessageId); var notification = new ObjectChanged { Change = change }; return(Session.SendMessage(header, notification)); }
/// <summary> /// Blocks until events are sent on the session, or timeout is reached, then processes any received events and adds them /// to eventQueue. This function implements the new event system, available in API version 1.9. /// In the new event system, (GetAllRecords + GetEvents) sequence will replace (RegisterForEvents + DownloadObjects + GetNextEvents). /// </summary> /// <param name="session"></param> /// <param name="eventQueue"></param> /// <param name="cancelled"></param> /// <param name="legacyEventSystem">True if legacy event system (event.next) should be used.</param> /// <param name="token">A token used by event.from(). /// It should be the empty string when event.from is first called, which is the replacement of get_all_records. /// </param> public static void GetEvents(Session session, LockFreeQueue <ObjectChange> eventQueue, HTTP.FuncBool cancelled, bool legacyEventSystem, ref string token) { if (legacyEventSystem) { GetNextEvents(session, eventQueue, cancelled); return; } Proxy_Event[] proxyEvents; try { var classes = new [] { "*" }; // classes that we are interested in receiving events from var eventResult = Event.from(session, classes, token, EVENT_FROM_TIMEOUT); token = eventResult.token; proxyEvents = eventResult.events; } catch (WebException e) { // Catch timeout, and turn it into an EventNextBlockedException so we can recognise it later (CA-33145) if (e.Status == WebExceptionStatus.Timeout) { throw new EventNextBlockedException(); } else { throw; } } if (cancelled()) { return; } //We want to do the marshalling on this bg thread so as not to block the gui thread foreach (Proxy_Event proxyEvent in proxyEvents) { ObjectChange objectChange = ProcessEvent(proxyEvent); if (objectChange != null) { eventQueue.Enqueue(objectChange); } } }
public static byte[] CreateInitPacket(ulong tickId, int id, int i, int j) { var builder = new FlatBufferBuilder(1); Packet.StartDataVector(builder, 1); ObjectChange.CreateObjectChange(builder, id, ObjectType.Player, i, j); var dataOffset = builder.EndVector(); Packet.StartPacket(builder); Packet.AddTickId(builder, tickId); Packet.AddType(builder, SuperPvp.Core.Transport.PacketType.Initialize); Packet.AddData(builder, dataOffset); var packet = Packet.EndPacket(builder); builder.Finish(packet.Value); return(builder.SizedByteArray()); }
/// <summary> /// Blocks until events are sent on the session, then processes any received events and adds them /// to eventQueue. Will always add at least one event to eventQueue. /// This function should be used with XenServer up to version 6.0. For XenServer higher than 6.0, GetEvents() should be used instead. /// </summary> /// <param name="session"></param> /// <param name="eventQueue"></param> /// <param name="cancelled"></param> public static void GetNextEvents(Session session, LockFreeQueue <ObjectChange> eventQueue, HTTP.FuncBool cancelled) { Proxy_Event[] proxyEvents; try { proxyEvents = Event.next(session); } catch (WebException e) { // Catch timeout, and turn it into an EventNextBlockedException so we can recognise it later (CA-33145) if (e.Status == WebExceptionStatus.Timeout) { throw new EventNextBlockedException(); } else { throw; } } if (proxyEvents.Length == 0) { throw new IOException("Event.next() returned no events; the server is misbehaving."); } if (cancelled()) { return; } //We want to do the marshalling on this bg thread so as not to block the gui thread foreach (Proxy_Event proxyEvent in proxyEvents) { ObjectChange objectChange = ProcessEvent(proxyEvent); if (objectChange != null) { eventQueue.Enqueue(objectChange); } } }
public static byte[] CreateCommandPacket(ulong tickId, ServerGameObject targetState) { var builder = new FlatBufferBuilder(1); Packet.StartDataVector(builder, 1); ObjectChange.CreateObjectChange(builder, targetState.Id, ObjectType.Player, targetState.Position.I, targetState.Position.J); var dataOffset = builder.EndVector(); Packet.StartPacket(builder); Packet.AddTickId(builder, tickId); Packet.AddType(builder, SuperPvp.Core.Transport.PacketType.Command); Packet.AddData(builder, dataOffset); var packet = Packet.EndPacket(builder); builder.Finish(packet.Value); return(builder.SizedByteArray()); }
public static byte[] CreateUpdatePacket(ulong tickId, List <ServerGameObject> changes) { var builder = new FlatBufferBuilder(1); Packet.StartDataVector(builder, changes.Count); foreach (var change in changes) { var type = change.Type == GameObjectType.Player ? ObjectType.Player : ObjectType.Drug; ObjectChange.CreateObjectChange(builder, change.Id, type, change.Position.I, change.Position.J); } var dataOffset = builder.EndVector(); Packet.StartPacket(builder); Packet.AddTickId(builder, tickId); Packet.AddType(builder, SuperPvp.Core.Transport.PacketType.Update); Packet.AddData(builder, dataOffset); var packet = Packet.EndPacket(builder); builder.Finish(packet.Value); return(builder.SizedByteArray()); }
private void UpdateFrom_ <T>(Network.IXenConnection connection, ChangeableDictionary <XenRef <T>, T> target, ObjectChange source) where T : XenObject <T>, new() { XenRef <T> xenref = source.xenref as XenRef <T>; if (xenref == null) { xenref = new XenRef <T>((string)source.xenref); } if (source.value != null) { T to_update = null; lock (target) { if (!target.TryGetValue(xenref, out to_update)) { // add T obj = new T(); obj.Connection = connection; obj.UpdateFrom((T)source.value); obj.opaque_ref = xenref.opaque_ref; target.Add(xenref, obj); } } // Update the object that we found above. Note that this needs to be done out of the // scope of the lock(target), as UpdateFrom is going to fire events. if (to_update != null) { to_update.UpdateFrom((T)source.value); } } else { // delete the source object from our model lock (target) { target.Remove(xenref); } } }
/// <summary> /// Sends a NotificationRequestDeleteNotification message to a customer. /// </summary> /// <param name="requestUuid">The request UUID.</param> /// <param name="change">The object change.</param> /// <returns>The sent message on success; <c>null</c> otherwise.</returns> public virtual EtpMessage <DeleteNotification> DeleteNotification(Guid requestUuid, ObjectChange change) { var subscription = TryGetSubscription <NotificationRequestRecord>(requestUuid); if (subscription == null) { return(null); } return(DeleteNotification(subscription?.Header, change)); }
/// <summary> /// Sends a ChangeNotification message to a customer. /// </summary> /// <param name="correlatedHeader">The message header that the message to send is correlated with.</param> /// <param name="change">The object change.</param> /// <returns>The sent message on success; <c>null</c> otherwise.</returns> public virtual EtpMessage <ChangeNotification> ChangeNotification(IMessageHeader correlatedHeader, ObjectChange change) { var body = new ChangeNotification() { Change = change, }; return(SendNotification(body, correlatedHeader: correlatedHeader)); }