private const double EVENT_FROM_TIMEOUT = 30; // 30 seconds /// <summary> /// Gets all objects from the server. Used in order to fill the cache. /// This function implements the new event system, available from in API version 1.9. /// In the new event system, (GetAllRecords + GetEvents) sequence will replace (RegisterForEvents + DownloadObjects + GetNextEvents). /// </summary> /// <param name="session">The session over which to download the objects. Must not be null.</param> /// <param name="changes">The queue that the ObjectChanges will be put into. Must not be null.</param> /// <param name="cancelled">Used by GetEvents().</param> /// <param name="token">Used by GetEvents().</param> public static void GetAllObjects(Session session, LockFreeQueue <ObjectChange> changes, HTTP.FuncBool cancelled, ref string token) { // download objects that are not covered by event.from(), e.g. Roles var roleRecords = Role.get_all_records(session); foreach (KeyValuePair <XenRef <Role>, Role> entry in roleRecords) { changes.Enqueue(new ObjectChange(typeof(Role), entry.Key.opaque_ref, entry.Value)); } // get all objects with event.from() token = ""; GetEvents(session, changes, cancelled, ref token); }
/// <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="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, ref string token) { 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 EventFromBlockedException so we can recognise it later (CA-33145) if (e.Status == WebExceptionStatus.Timeout) { throw new EventFromBlockedException(); } 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 LockFreeQueueEnumerator(LockFreeQueue <U> queue) { this.queue = queue; this.current = queue.head; }
/// <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="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, ref string token) { Proxy_Event[] proxyEvents = {}; Event[] events = {}; try { var classes = new [] { "*" }; // classes that we are interested in receiving events from var eventResult = Event.from(session, classes, token, EVENT_FROM_TIMEOUT); if (session.JsonRpcClient != null) { var batch = (EventBatch)eventResult; events = batch.events; token = batch.token; } else { var evts = (Events)eventResult; proxyEvents = evts.events; token = evts.token; } } catch (WebException e) { // Catch timeout, and turn it into an EventFromBlockedException so we can recognise it later (CA-33145) if (e.Status == WebExceptionStatus.Timeout) { throw new EventFromBlockedException(); } else { throw; } } if (cancelled()) { return; } //We want to do the marshalling on this background thread so as not to block the gui thread if (session.JsonRpcClient != null) { foreach (Event evt in events) { var objectChange = ProcessEvent(evt.class_, evt.operation, evt.opaqueRef, evt.snapshot, false); if (objectChange != null) { eventQueue.Enqueue(objectChange); } } } else { foreach (Proxy_Event proxyEvent in proxyEvents) { var objectChange = ProcessEvent(proxyEvent.class_, proxyEvent.operation, proxyEvent.opaqueRef, proxyEvent.snapshot, true); if (objectChange != null) { eventQueue.Enqueue(objectChange); } } } }