示例#1
0
        public async Task DispatchEffectsAsync(PropagationEffects effects)
        {
            await StatsHelper.RegisterMsg("EffectsDispatcherGrain::DispatchEffects", this.GrainFactory);

            Logger.LogInfoForDebug(this.GetLogger(), "@@[Dispatcher {0}] Dequeuing effects", this.GetPrimaryKey());

            this.lastProcessingTime   = DateTime.UtcNow;
            this.isDispatchingEffects = true;

            if (this.status != EffectsDispatcherStatus.Busy)
            {
                Logger.LogForRelease(this.GetLogger(), "@@[Dispatcher {0}] Becoming busy (before was {1})", this.GetPrimaryKey(), this.status);

                var oldStatus = this.status;
                this.status = EffectsDispatcherStatus.Busy;

                if (oldStatus == EffectsDispatcherStatus.Idle)
                {
                    // Notify that the dispatcher is busy
                    this.subscriptionManager.Notify(s => s.OnEffectsDispatcherStatusChanged(this, this.status));
                }
            }

            await this.effectsDispatcher.DispatchEffectsAsync(effects);

            this.lastProcessingTime   = DateTime.UtcNow;
            this.isDispatchingEffects = false;
        }
        private async Task PropagateEffectsAsync(PropagationEffects propagationEffects, PropagationKind propKind, IMethodEntityWithPropagator methodEntityProp = null)
        {
            //var hasMoreEffects = true;

            //do
            //{
            //Logger.LogS("AnalysisOrchestator", "DoPropagationOfEffects", "");

            if (GrainClient.IsInitialized)
            {
                Logger.LogInfo(GrainClient.Logger, "Orchestrator", "PropagatEffFects", "Propagating effets computed in {0}", propagationEffects.SiloAddress);
            }

            await this.ProcessCalleesAsync(propagationEffects.CalleesInfo, propKind);

            if (propagationEffects.ResultChanged)
            {
                await this.ProcessReturnAsync(propagationEffects.CallersInfo, propKind);
            }

            //hasMoreEffects = propagationEffects.MoreEffectsToFetch;

            //if (hasMoreEffects && methodEntityProp != null)
            //{
            //	propagationEffects = await methodEntityProp.GetMoreEffects();
            //}
            //}
            //while (hasMoreEffects);
        }
示例#3
0
        private async Task PopulatePropagationEffectsInfo(PropagationEffects propagationEffects, PropagationKind propKind)
        {
            await this.PopulateCalleesInfo(propagationEffects.CalleesInfo);

            if (this.methodEntity.ReturnVariable != null || propKind == PropagationKind.REMOVE_TYPES)
            {
                this.PopulateCallersInfo(propagationEffects.CallersInfo);
            }
        }
示例#4
0
        private async Task <PropagationEffects> InternalPropagateAsync(PropagationKind propKind)
        {
            //Logger.LogS("MethodEntityProp", "PropagateAsync", "Propagation for {0} ", this.methodEntity.MethodDescriptor);
            //Logger.Log("Propagating {0} to {1}", this.methodEntity.MethodDescriptor, propKind);

            // var codeProvider = await ProjectGrainWrapper.CreateProjectGrainWrapperAsync(this.methodEntity.MethodDescriptor);
            PropagationEffects propagationEffects = null;

            switch (propKind)
            {
            case PropagationKind.ADD_TYPES:
                propagationEffects = await this.methodEntity.PropGraph.PropagateAsync(codeProvider);

                break;

            case PropagationKind.REMOVE_TYPES:
                propagationEffects = await this.methodEntity.PropGraph.PropagateDeletionAsync(codeProvider);

                break;

            default:
                throw new Exception("Unsupported propagation kind");
            }

            await this.PopulatePropagationEffectsInfo(propagationEffects, propKind);

            Logger.LogS("MethodEntityGrain", "PropagateAsync", "End Propagation for {0} ", this.methodEntity.MethodDescriptor);
            //this.methodEntity.Save(@"C:\Temp\"+this.methodEntity.MethodDescriptor.MethodName + @".dot");

            //if (propagationEffects.CalleesInfo.Count > 100)
            //{
            //	int index = 0;
            //	var count = propagationEffects.CalleesInfo.Count;
            //	var callessInfo = propagationEffects.CalleesInfo.ToList();
            //	propagationEffects.CalleesInfo = new HashSet<CallInfo>(callessInfo.GetRange(index, count > 100 ? 100 : count));
            //	propagationEffects.MoreEffectsToFetch = true;
            //
            //	while (count > 100)
            //	{
            //		count -= 100;
            //		index += 100;
            //
            //		var propEffect = new PropagationEffects(new HashSet<CallInfo>(callessInfo.GetRange(index, count > 100 ? 100 : count)), false);
            //
            //		if (count > 100)
            //		{
            //			propEffect.MoreEffectsToFetch = true;
            //		}
            //
            //		this.propagationEffectsToSend.Enqueue(propEffect);
            //	}
            //}
            //this.UpdateHistory.Add(this.methodEntity.PropGraph.UpdateCount);
            return(propagationEffects);
        }
        // This doesn't work with circular references present in effects (MethodDescriptor.BaseDescriptor)
        //private string SerializeEffects(PropagationEffects effects)
        //{
        //	var result = string.Empty;
        //	var serializer = Newtonsoft.Json.JsonSerializer.CreateDefault();

        //	using (var writer = new StringWriter())
        //	{
        //		serializer.Serialize(writer, effects);
        //		result = writer.ToString();
        //	}

        //	return result;
        //}

        private static IEnumerable <PropagationEffects> SplitEffects(PropagationEffects effects, int maxCallSiteCount, int maxCallersCount)
        {
            var result      = new List <PropagationEffects>();
            var calleesInfo = effects.CalleesInfo.ToList();
            //var calleesInfo = SplitCalleesInfo(effects.CalleesInfo, maxCount);
            var count = calleesInfo.Count;
            var index = 0;

            while (count > maxCallSiteCount)
            {
                var callees = calleesInfo.GetRange(index, maxCallSiteCount);
                var message = new PropagationEffects(callees, false);

                result.Add(message);

                count -= maxCallSiteCount;
                index += maxCallSiteCount;
            }

            if (count > 0)
            {
                var callees = calleesInfo.GetRange(index, count);
                var message = new PropagationEffects(callees, false);

                result.Add(message);
            }

            if (effects.ResultChanged)
            {
                var callersInfo = effects.CallersInfo.ToList();
                count = callersInfo.Count;
                index = 0;

                while (count > maxCallersCount)
                {
                    var callers = callersInfo.GetRange(index, maxCallersCount);
                    var message = new PropagationEffects(callers);

                    result.Add(message);

                    count -= maxCallersCount;
                    index += maxCallersCount;
                }

                if (count > 0)
                {
                    var callers = callersInfo.GetRange(index, count);
                    var message = new PropagationEffects(callers);

                    result.Add(message);
                }
            }

            return(result);
        }
示例#6
0
        public async Task DispatchEffectsAsync(PropagationEffects effects)
        {
            Logger.LogS("EffectsDispatcherManager", "DispatchEffects", "Propagating effects computed in {0}", effects.SiloAddress);

            await this.ProcessCalleesAsync(effects.CalleesInfo, effects.Kind);

            if (effects.ResultChanged)
            {
                await this.ProcessReturnAsync(effects.CallersInfo, effects.Kind);
            }
        }
示例#7
0
        internal async Task PropagateEffectsAsync(PropagationEffects propagationEffects, PropagationKind propKind, IMethodEntityWithPropagator methodEntityProp = null)
        {
            Logger.LogInfo(Logger.OrleansLogger, "SiloOrchestrator", "PropagatEffFects", "Propagating effets computed in {0}", propagationEffects.SiloAddress);

            await this.ProcessCalleesAsync(propagationEffects.CalleesInfo, propKind);

            if (propagationEffects.ResultChanged)
            {
                await this.ProcessReturnAsync(propagationEffects.CallersInfo, propKind);
            }

            await ProcessMessages();
        }
        private async Task SplitAndEnqueueEffectsAsync(PropagationEffects effects, int maxCallSitesCount, int maxCallersCount, int maxCalleesCount)
        {
            var tasks    = new List <Task>();
            var messages = SplitEffects(effects, maxCallSitesCount, maxCallersCount);

            foreach (var message in messages)
            {
                var task = this.EnqueueEffectsAsync(message, maxCallSitesCount, maxCallersCount, maxCalleesCount);
                //await task;
                tasks.Add(task);
            }

            await Task.WhenAll(tasks);
        }
        private static List <PropagationEffects> SplitCallSite(PropagationEffects effects, int maxCallees)
        {
            var result      = new List <PropagationEffects>();
            var calleesInfo = SplitCalleesInfo(effects.CalleesInfo, maxCallees);

            foreach (var callInfo in calleesInfo)
            {
                var callees = new CallInfo[] { callInfo };
                var message = new PropagationEffects(callees, false);

                result.Add(message);
            }

            return(result);
        }
        private async Task ProcessEffectsAsync(PropagationEffects effects, PropagationKind propKind = PropagationKind.ADD_TYPES)
        {
            effects.Kind = propKind;

            var maxCallSitesCount = Math.Min(effects.CalleesInfo.Count, 8);
            var maxCallersCount   = Math.Min(effects.CallersInfo.Count, 8);

            // This is an optimization, it is not really needed
            if (maxCallSitesCount == 0 && maxCallersCount == 0)
            {
                return;
            }

            await this.SplitAndEnqueueEffectsAsync(effects, maxCallSitesCount, maxCallersCount, int.MaxValue);
        }
示例#11
0
        public Task <PropagationEffects> RemoveMethodAsync()
        {
            var calleesInfo = from callNode in this.methodEntity.PropGraph.CallNodes
                              let calleeInfo = this.methodEntity.PropGraph.GetInvocationInfo(callNode)
                                               select calleeInfo.Clone(calleeInfo.PossibleCallees);

            //select calleeInfo;

            var propagationEffects = new PropagationEffects(calleesInfo, true);

            //await this.PopulatePropagationEffectsInfo(propagationEffects, PropagationKind.REMOVE_TYPES);
            //return propagationEffects;

            this.PopulateCallersInfo(propagationEffects.CallersInfo);
            return(Task.FromResult(propagationEffects));
        }
        private string GetEffectsInfo(PropagationEffects effects)
        {
            var callees     = 0;
            var arguments   = 0;
            var invocations = effects.CalleesInfo.Count;
            var callers     = effects.CallersInfo.Count;

            foreach (var calleeInfo in effects.CalleesInfo)
            {
                callees   += calleeInfo.PossibleCallees.Count;
                arguments += calleeInfo.ArgumentsPossibleTypes.Sum(ts => ts.Count);
            }

            var result = string.Format("invocations = {0}, callees = {1}, argument types = {2}, callers = {3}", invocations, callees, arguments, callers);

            return(result);
        }
        public async Task <PropagationEffects> AddMethodAsync(MethodDescriptor methodToAdd)
        {
            PropagationEffects effects    = null;
            var overridenMethodDescriptor = await GetOverridenMethodAsync(methodToAdd);

            if (overridenMethodDescriptor != null)
            {
                var methodEntityWP = await this.GetMethodEntityAsync(overridenMethodDescriptor);

                effects = await methodEntityWP.RemoveMethodAsync();
            }
            else
            {
                effects = new PropagationEffects();
            }

            return(effects);
        }
示例#14
0
 public Task OnNextAsync(PropagationEffects item, StreamSequenceToken token = null)
 {
     return(this.DispatchEffectsAsync(item));
 }
        private async Task EnqueueEffectsAsync(PropagationEffects effects, int maxCallSitesCount, int maxCallersCount, int maxCalleesCount)
        {
            var splitEffects = false;
            var splitCallees = false;
            var retryCount   = AnalysisConstants.StreamCount;           // 3

            do
            {
                var stream = this.SelectStream();

                try
                {
                    await stream.OnNextAsync(effects);

                    break;
                }
                catch (Exception ex)
                {
                    var innerEx = ex;
                    while (innerEx is AggregateException)
                    {
                        innerEx = innerEx.InnerException;
                    }

                    if (innerEx is ArgumentException)
                    {
                        if (maxCallSitesCount > 1 || maxCallersCount > 1)
                        {
                            // Messages cannot be larger than 65536 bytes
                            splitEffects = true;
                            break;
                        }
                        else if (maxCalleesCount > 1)
                        {
                            splitCallees = true;
                            break;
                        }
                        else
                        {
                            retryCount--;

                            if (retryCount == 0)
                            {
                                //var effectsInfo = this.SerializeEffects(effects);
                                var effectsInfo = this.GetEffectsInfo(effects);
                                Logger.LogError(this.GetLogger(), "MethodEntityGrain", "EnqueueEffects", "Exception on OnNextAsync (maxCallSiteCount = {0}, {1})\n{2}", maxCallSitesCount, effectsInfo, ex);
                                //throw ex;
                            }
                        }
                    }
                    else
                    {
                        retryCount--;

                        if (retryCount == 0)
                        {
                            //var effectsInfo = this.SerializeEffects(effects);
                            var effectsInfo = this.GetEffectsInfo(effects);
                            Logger.LogError(this.GetLogger(), "MethodEntityGrain", "EnqueueEffects", "Exception on OnNextAsync (maxCallSiteCount = {0}, {1})\n{2}", maxCallSitesCount, effectsInfo, ex);
                            //throw ex;
                        }
                    }
                }
            }while (retryCount > 0);

            if (splitEffects)
            {
                var newMaxCallSitesCount = maxCallSitesCount;
                var newMaxCallersCount   = maxCallersCount;

                if (maxCallSitesCount > 1)
                {
                    newMaxCallSitesCount = (maxCallSitesCount / 2) + (maxCallSitesCount % 2);

                    Logger.LogForRelease(this.GetLogger(), "@@[MethodEntityGrain {0}] Splitting effects (call sites) of size {1} into parts of size {2}", this.methodEntity.MethodDescriptor, maxCallSitesCount, newMaxCallSitesCount);
                }
                else if (maxCallersCount > 1)
                {
                    newMaxCallersCount = (maxCallersCount / 2) + (maxCallersCount % 2);

                    Logger.LogForRelease(this.GetLogger(), "@@[MethodEntityGrain {0}] Splitting effects (callers) of size {1} into parts of size {2}", this.methodEntity.MethodDescriptor, maxCallersCount, newMaxCallersCount);
                }

                await this.SplitAndEnqueueEffectsAsync(effects, newMaxCallSitesCount, newMaxCallersCount, maxCalleesCount);
            }

            if (splitCallees)
            {
                var calleeInfo = effects.CalleesInfo.Single();

                if (calleeInfo.PossibleCallees != null)
                {
                    maxCalleesCount = Math.Min(calleeInfo.PossibleCallees.Count, maxCalleesCount);
                    var newMaxCalleesCount = (maxCalleesCount / 2) + (maxCalleesCount % 2);

                    Logger.LogForRelease(this.GetLogger(), "@@[MethodEntityGrain {0}] Splitting effects (callees of) {1} call site into parts of size {2}", this.methodEntity.MethodDescriptor, maxCallSitesCount, newMaxCalleesCount);

                    await this.SplitAndEnqueueCalleeEffectsAsync(effects, maxCallSitesCount, maxCallersCount, newMaxCalleesCount);
                }
            }
        }