Exemple #1
0
 public EPEventServiceThreadLocalEntry(
     DualWorkQueue<object> dualWorkQueue,
     ArrayBackedCollection<FilterHandle> matchesArrayThreadLocal,
     ArrayBackedCollection<ScheduleHandle> scheduleArrayThreadLocal,
     IDictionary<EPStatementAgentInstanceHandle, object> matchesPerStmtThreadLocal,
     IDictionary<EPStatementAgentInstanceHandle, object> schedulePerStmtThreadLocal,
     ExprEvaluatorContext exprEvaluatorContext)
 {
     DualWorkQueue = dualWorkQueue;
     MatchesArrayThreadLocal = matchesArrayThreadLocal;
     ScheduleArrayThreadLocal = scheduleArrayThreadLocal;
     MatchesPerStmtThreadLocal = matchesPerStmtThreadLocal;
     SchedulePerStmtThreadLocal = schedulePerStmtThreadLocal;
     ExprEvaluatorContext = exprEvaluatorContext;
 }
        public static IThreadLocal <EPEventServiceThreadLocalEntry> AllocateThreadLocals(
            bool isPrioritized,
            string runtimeURI,
            EventBeanService eventBeanService,
            ExceptionHandlingService exceptionHandlingService,
            SchedulingService schedulingService)
        {
            return(new FastThreadLocal <EPEventServiceThreadLocalEntry>(
                       () => {
                DualWorkQueue <object> dualWorkQueue = new DualWorkQueue <object>();
                ArrayBackedCollection <FilterHandle> filterHandles = new ArrayBackedCollection <FilterHandle>(100);
                ArrayBackedCollection <ScheduleHandle> scheduleHandles = new ArrayBackedCollection <ScheduleHandle>(100);

                IDictionary <EPStatementAgentInstanceHandle, object> matchesPerStmt;
                IDictionary <EPStatementAgentInstanceHandle, object> schedulesPerStmt;
                if (isPrioritized)
                {
                    matchesPerStmt = new SortedDictionary <EPStatementAgentInstanceHandle, object>(EPStatementAgentInstanceHandleComparer.INSTANCE);
                    schedulesPerStmt = new SortedDictionary <EPStatementAgentInstanceHandle, object>(EPStatementAgentInstanceHandleComparer.INSTANCE);
                }
                else
                {
                    matchesPerStmt = new Dictionary <EPStatementAgentInstanceHandle, object>();
                    schedulesPerStmt = new Dictionary <EPStatementAgentInstanceHandle, object>();
                }

                ExprEvaluatorContext runtimeFilterAndDispatchTimeContext = new EPEventServiceExprEvaluatorContext(
                    runtimeURI,
                    eventBeanService,
                    exceptionHandlingService,
                    schedulingService);
                return new EPEventServiceThreadLocalEntry(
                    dualWorkQueue,
                    filterHandles,
                    scheduleHandles,
                    matchesPerStmt,
                    schedulesPerStmt,
                    runtimeFilterAndDispatchTimeContext);
            }));
        }
        private void ProcessSchedule()
        {
            ArrayBackedCollection <ScheduleHandle> handles = ScheduleArray;

            // Evaluation of schedules is protected by an optional scheduling service lock and then the engine lock
            // We want to stay in this order for allowing the engine lock as a second-order lock to the
            // services own lock, if it has one.
            using (_unisolatedServices.EventProcessingRWLock.AcquireReadLock())
            {
                _services.SchedulingService.Evaluate(handles);
            }
            using (_unisolatedServices.EventProcessingRWLock.AcquireReadLock())
            {
                try
                {
                    ProcessScheduleHandles(handles);
                }
                catch (Exception)
                {
                    handles.Clear();
                    throw;
                }
            }
        }
        private void ProcessScheduleHandles(ArrayBackedCollection <ScheduleHandle> handles)
        {
            if (ThreadLogUtil.ENABLED_TRACE)
            {
                ThreadLogUtil.Trace("Found schedules for", handles.Count);
            }

            if (handles.Count == 0)
            {
                return;
            }

            // handle 1 result separatly for performance reasons
            if (handles.Count == 1)
            {
                Object[] handleArray = handles.Array;
                var      handle      = (EPStatementHandleCallback)handleArray[0];

                EPRuntimeImpl.ProcessStatementScheduleSingle(handle, _unisolatedServices);

                handles.Clear();
                return;
            }

            Object[] matchArray = handles.Array;
            int      entryCount = handles.Count;

            LinkedList <ScheduleHandleCallback> entries;

            // sort multiple matches for the event into statements
            var stmtCallbacks = SchedulePerStmt;

            stmtCallbacks.Clear();
            for (int i = 0; i < entryCount; i++)
            {
                var handleCallback = (EPStatementHandleCallback)matchArray[i];
                var handle         = handleCallback.AgentInstanceHandle;
                var callback       = handleCallback.ScheduleCallback;

                var entry = stmtCallbacks.Get(handle);

                // This statement has not been encountered before
                if (entry == null)
                {
                    stmtCallbacks.Put(handle, callback);
                    continue;
                }

                // This statement has been encountered once before
                if (entry is ScheduleHandleCallback)
                {
                    var existingCallback = (ScheduleHandleCallback)entry;
                    entries = new LinkedList <ScheduleHandleCallback>();
                    entries.AddLast(existingCallback);
                    entries.AddLast(callback);
                    stmtCallbacks.Put(handle, entries);
                    continue;
                }

                // This statement has been encountered more then once before
                entries = (LinkedList <ScheduleHandleCallback>)entry;
                entries.AddLast(callback);
            }
            handles.Clear();

            foreach (var entry in stmtCallbacks)
            {
                var handle         = entry.Key;
                var callbackObject = entry.Value;

                EPRuntimeImpl.ProcessStatementScheduleMultiple(handle, callbackObject, _unisolatedServices);

                if ((_isPrioritized) && (handle.IsPreemptive))
                {
                    break;
                }
            }
        }