public IOriCollection Merge(ICUDResult cudResult, IMethodDescription methodDescription) { ParamChecker.AssertParamNotNull(cudResult, "cudResult"); long?startTime = startTimeTL.Value; bool startTimeHasBeenSet = false; if (!startTime.HasValue) { startTime = DateTimeUtil.CurrentTimeMillis(); startTimeTL.Value = startTime; startTimeHasBeenSet = true; } try { if (Transaction == null || Transaction.Active) { return(MergeIntern(cudResult, methodDescription)); } return(Transaction.RunInLazyTransaction(delegate() { return MergeIntern(cudResult, methodDescription); })); } finally { if (startTimeHasBeenSet) { startTimeTL.Value = null; } } }
private object CallInSyncContext(IMethodDescription methodDescription, object[] parameters) { object result = null; Exception exception = null; var resetEvent = new AutoResetEvent(false); _synchronizationContext.Post(s => { try { result = methodDescription.Method.Invoke(Object, parameters); } catch (Exception e) { exception = e; } resetEvent.Set(); }, null); resetEvent.WaitOne(); if (exception != null) { throw exception; } return(result); }
private void CreateMethod(IMethodDescription methodDescription) { var returnType = methodDescription.ReturnType.Type; var method = _typeBuilder.DefineMethod(methodDescription.Name, MethodAttributes.Public | MethodAttributes.Virtual, CallingConventions.Standard | CallingConventions.HasThis, returnType, methodDescription.Parameters.Select(x => x.ParameterType.Type).ToArray()); var gen = method.GetILGenerator(); if (returnType != typeof(void)) { if (returnType.IsValueType) { var local = gen.DeclareLocal(returnType); gen.Emit(OpCodes.Ldloca, local); gen.Emit(OpCodes.Initobj, returnType); gen.Emit(OpCodes.Ldloc, local); } else { gen.Emit(OpCodes.Ldnull); } } gen.Emit(OpCodes.Ret); }
private void CreateMethod(IMethodDescription methodDescription) { var method = methodDescription.Method; var parameters = methodDescription.Parameters; var methodAttributes = MethodAttributes.Public | MethodAttributes.Virtual; var methodBuilder = _typeBuilder.DefineMethod(methodDescription.Name, methodAttributes, method.ReturnType, parameters.Select(x => x.ParameterType.Type).ToArray()); var gen = methodBuilder.GetILGenerator(); if (methodDescription.IsAsync) { gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldfld, _subject); for (int i = 0; i < methodDescription.Parameters.Count; ++i) { gen.Emit(OpCodes.Ldarg, i + 1); } gen.Emit(OpCodes.Callvirt, methodDescription.Method); } else { ConstructorInfo constructor; MethodInfo run; List <FieldInfo> fields; var lambdaType = CreateLambdaStorageClass(methodDescription, out fields, out constructor, out run); var lambda = gen.DeclareLocal(lambdaType); gen.Emit(OpCodes.Newobj, constructor); gen.Emit(OpCodes.Stloc, lambda); for (int i = 0; i < methodDescription.Parameters.Count; ++i) { gen.Emit(OpCodes.Ldloc, lambda); gen.Emit(OpCodes.Ldarg, i + 1); gen.Emit(OpCodes.Stfld, fields[i]); } gen.Emit(OpCodes.Ldloc, lambda); gen.Emit(OpCodes.Ldftn, run); gen.Emit(OpCodes.Newobj, Methods.ActionIntPtrCtor); gen.Emit(OpCodes.Call, Methods.TaskFactoryStartNew); } gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldfld, _timeout); gen.Emit(OpCodes.Call, Methods.TaskExTimeoutAfter); gen.Emit(OpCodes.Ret); _typeBuilder.DefineMethodOverride(methodBuilder, methodDescription.Method); }
public AsyncStateMachineCompiler(TypeBuilder typeBuilder, ITypeDescription interfaceDescription, IMethodDescription methodDescription) { _originalMethod = methodDescription.Method; var taskType = methodDescription.ReturnType.Type; _taskGetAwaiter = taskType.GetMethod(nameof(Task.GetAwaiter)); _awaiterType = GetAwaiterType(taskType); _awaiterOnCompleted = _awaiterType.GetMethod(nameof(TaskAwaiter.OnCompleted), new[] { typeof(Action) }); var taskReturnType = GetTaskReturnType(taskType); _hasReturnValue = taskReturnType != typeof(void); if (_hasReturnValue) { _taskGetResult = taskType.GetProperty(nameof(Task <int> .Result)).GetMethod; } var interfaceType = interfaceDescription.Type; _taskCompletionSourceType = GetTaskCompletionSourceType(taskType); _taskCompletionSourceSetResult = _taskCompletionSourceType.GetMethod(nameof(TaskCompletionSource <int> .SetResult)); _taskCompletionSourceSetException = _taskCompletionSourceType.GetMethod(nameof(TaskCompletionSource <int> .SetException), new [] { typeof(Exception) }); _taskCompletionSourceSetExceptions = _taskCompletionSourceType.GetMethod(nameof(TaskCompletionSource <int> .SetException), new [] { typeof(IEnumerable <Exception>) }); _taskCompletionSourceGetTask = _taskCompletionSourceType.GetProperty(nameof(TaskCompletionSource <int> .Task)) .GetMethod; var name = string.Format("{0}_AsyncStateMachine", methodDescription.Name); _stateMachine = typeBuilder.DefineNestedType(name); _subject = _stateMachine.DefineField("Subject", taskType, FieldAttributes.Public); _fallback = _stateMachine.DefineField("Fallback", interfaceType, FieldAttributes.Public); _subjectTask = _stateMachine.DefineField("_subjectTask", taskType, FieldAttributes.Private); _fallbackTask = _stateMachine.DefineField("_fallbackTask", taskType, FieldAttributes.Private); _taskCompletionSource = _stateMachine.DefineField("TaskCompletionSource", _taskCompletionSourceType, FieldAttributes.Public | FieldAttributes.InitOnly); _parameters = new List <FieldInfo>(methodDescription.Parameters.Count); foreach (var parameter in methodDescription.Parameters) { var parameterName = string.Format("parameter_{0}", parameter.Name); var field = _stateMachine.DefineField(parameterName, parameter.ParameterType.Type, FieldAttributes.Public); _parameters.Add(field); } }
private static void ThrowIfIncompatible(IMethodDescription expectedDescription, MethodDescription actualDescription) { ThrowIfIncompatible(expectedDescription.ReturnParameter, actualDescription.ReturnParameter); if (expectedDescription.Parameters.Count != actualDescription.Parameters.Length) { throw new NotImplementedException($"The remote method has a different amount of parameters: Expected {expectedDescription} but found {actualDescription}"); } for (int i = 0; i < expectedDescription.Parameters.Count; ++i) { var expectedParameter = expectedDescription.Parameters[i]; var actualParameter = actualDescription.Parameters[i]; ThrowIfIncompatible(expectedParameter, actualParameter); } }
private bool OperationWithArguments(IMethodDescription methodDescription, object[] invocationArguments) { var parameters = methodDescription.Method.GetParameters(); return(parameters.Length == invocationArguments.Length && parameters.Zip( invocationArguments, (p, ia) => { if (ia == null) { // Check if null can be assigned to the parameter type var canBeNull = !p.ParameterType.IsValueType || Nullable.GetUnderlyingType(p.ParameterType) != null; return canBeNull; } return p.ParameterType.IsInstanceOfType(ia); }).All(p => p)); }
protected ICUDResult WhatIfMerged(ICUDResult cudResult, IMethodDescription methodDescription, List <MergeOperation> mergeOperationSequence, IncrementalMergeState incrementalState) { IList <MergeOperation> lastMergeOperationSequence; while (true) { IMap <Type, IList <IChangeContainer> > sortedChanges = BucketSortChanges(cudResult.AllChanges); lastMergeOperationSequence = CreateMergeOperationSequence(sortedChanges); ParamHolder <bool> hasAtLeastOneImplicitChange = new ParamHolder <bool>(false); IList <MergeOperation> fLastMergeOperationSequence = lastMergeOperationSequence; cudResult = CacheContext.ExecuteWithCache(incrementalState.GetStateCache(), delegate(ICUDResult cudResult2) { for (int a = 0, size = fLastMergeOperationSequence.Count; a < size; a++) { MergeOperation mergeOperation = fLastMergeOperationSequence[a]; IMergeServiceExtension mergeServiceExtension = mergeOperation.MergeServiceExtension; ICUDResult explAndImplCudResult = mergeServiceExtension.EvaluateImplicitChanges(cudResult2, incrementalState); cudResult2 = MergeCudResult(cudResult2, explAndImplCudResult, mergeServiceExtension, hasAtLeastOneImplicitChange, incrementalState); } return(cudResult2); }, cudResult); foreach (IMergeListener mergeListener in mergeListeners.GetExtensions()) { ICUDResult explAndImplCudResult = mergeListener.PreMerge(cudResult, incrementalState.GetStateCache()); cudResult = MergeCudResult(cudResult, explAndImplCudResult, mergeListener, hasAtLeastOneImplicitChange, incrementalState); } if (!hasAtLeastOneImplicitChange.Value) { break; } } mergeOperationSequence.AddRange(lastMergeOperationSequence); return(cudResult); }
private Type CreateLambdaStorageClass(IMethodDescription methodDescription, out List <FieldInfo> fields, out ConstructorInfo constructor, out MethodInfo run) { var name = string.Format("{0}_State", methodDescription.Name); var lambdaType = _typeBuilder.DefineNestedType(name); fields = new List <FieldInfo>(methodDescription.Parameters.Count); foreach (var parameter in methodDescription.Parameters) { var field = lambdaType.DefineField(parameter.Name, parameter.ParameterType.Type, FieldAttributes.Public); fields.Add(field); } var ctor = lambdaType.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard | CallingConventions.HasThis, new Type[0]); var gen = ctor.GetILGenerator(); gen.Emit(OpCodes.Ret); constructor = ctor; var method = lambdaType.DefineMethod("Run", MethodAttributes.Public, CallingConventions.Standard | CallingConventions.HasThis, typeof(void), new Type[0]); gen = method.GetILGenerator(); gen.Emit(OpCodes.Ret); run = method; return(lambdaType.CreateType()); }
private void CreateMethod(IMethodDescription methodDescription) { var method = methodDescription.Method; var parameters = methodDescription.Parameters; var methodAttributes = MethodAttributes.Public | MethodAttributes.Virtual; var methodBuilder = _typeBuilder.DefineMethod(methodDescription.Name, methodAttributes, method.ReturnType, parameters.Select(x => x.ParameterType.Type).ToArray()); var gen = methodBuilder.GetILGenerator(); var exception = gen.DeclareLocal(typeof(Exception)); LocalBuilder returnValue = null; var hasReturnValue = method.ReturnType != typeof(void); if (hasReturnValue) { returnValue = gen.DeclareLocal(method.ReturnType); } gen.BeginExceptionBlock(); if (methodDescription.IsAsync) { var compiler = new AsyncStateMachineCompiler(_typeBuilder, _interfaceDescription, methodDescription); compiler.Compile(gen, _subject, _fallback, returnValue); } else { gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldfld, _subject); for (var i = 0; i < parameters.Count; ++i) { gen.Emit(OpCodes.Ldarg, i + 1); } gen.Emit(OpCodes.Callvirt, methodDescription.Method); if (hasReturnValue) { gen.Emit(OpCodes.Stloc, returnValue); } } gen.BeginCatchBlock(typeof(Exception)); gen.Emit(OpCodes.Stloc, exception); gen.EmitWriteLine(string.Format("Caught exception in {0}", methodDescription.Name)); gen.EmitWriteLine(exception); gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldfld, _fallback); for (var i = 0; i < parameters.Count; ++i) { gen.Emit(OpCodes.Ldarg, i + 1); } gen.Emit(OpCodes.Callvirt, methodDescription.Method); if (hasReturnValue) { gen.Emit(OpCodes.Stloc, returnValue); } gen.EndExceptionBlock(); if (hasReturnValue) { gen.Emit(OpCodes.Ldloc, returnValue); } gen.Emit(OpCodes.Ret); _typeBuilder.DefineMethodOverride(methodBuilder, methodDescription.Method); }
protected IOriCollection Intern(ICUDResult cudResult, IMethodDescription methodDescription, IList <MergeOperation> mergeOperationSequence, IncrementalMergeState state) { IList <IChangeContainer> allChanges = cudResult.AllChanges; IList <Object> originalRefs = cudResult.GetOriginalRefs(); IdentityHashMap <IChangeContainer, int> changeToChangeIndexDict = new IdentityHashMap <IChangeContainer, int>(); for (int a = allChanges.Count; a-- > 0;) { changeToChangeIndexDict.Put(allChanges[a], a); } IObjRef[] objRefs = new IObjRef[allChanges.Count]; long[] allChangedOn = new long[allChanges.Count]; String[] allChangedBy = new String[allChanges.Count]; CHashSet <long> changedOnSet = new CHashSet <long>(); CHashSet <String> changedBySet = new CHashSet <String>(); for (int a = 0, size = mergeOperationSequence.Count; a < size; a++) { MergeOperation mergeOperation = mergeOperationSequence[a]; IMergeServiceExtension mergeServiceExtension = mergeOperation.MergeServiceExtension; IList <IChangeContainer> changesForMergeService = mergeOperation.ChangeContainer; ICUDResult msCudResult = BuildCUDResult(changesForMergeService, changeToChangeIndexDict, originalRefs); IOriCollection msOriCollection = mergeServiceExtension.Merge(msCudResult, methodDescription); MergeController.ApplyChangesToOriginals(msCudResult, msOriCollection, state.GetStateCache()); IList <IObjRef> allChangeORIs = msOriCollection.AllChangeORIs; long? msDefaultChangedOn = msOriCollection.ChangedOn; String msDefaultChangedBy = msOriCollection.ChangedBy; long[] msAllChangedOn = msOriCollection.AllChangedOn; String[] msAllChangedBy = msOriCollection.AllChangedBy; for (int b = changesForMergeService.Count; b-- > 0;) { int index = changeToChangeIndexDict.Get(changesForMergeService[b]); objRefs[index] = allChangeORIs[b]; if (msAllChangedOn != null) { long msChangedOn = msAllChangedOn[b]; allChangedOn[index] = msChangedOn; changedOnSet.Add(msChangedOn); } else { allChangedOn[index] = msDefaultChangedOn.Value; } if (msAllChangedBy != null) { String msChangedBy = msAllChangedBy[b]; allChangedBy[index] = msChangedBy; changedBySet.Add(msChangedBy); } else { allChangedBy[index] = msDefaultChangedBy; } } if (msDefaultChangedOn != null) { changedOnSet.Add(msDefaultChangedOn.Value); } if (msDefaultChangedBy != null) { changedBySet.Add(msDefaultChangedBy); } } OriCollection oriCollection = new OriCollection(); oriCollection.AllChangeORIs = new List <IObjRef>(objRefs); if (changedBySet.Count == 1) { Iterator <String> iter = changedBySet.Iterator(); iter.MoveNext(); oriCollection.ChangedBy = iter.Current; } else { oriCollection.AllChangedBy = allChangedBy; } if (changedOnSet.Count == 1) { Iterator <long> iter = changedOnSet.Iterator(); iter.MoveNext(); oriCollection.ChangedOn = iter.Current; } else { oriCollection.AllChangedOn = allChangedOn; } foreach (IMergeListener mergeListener in mergeListeners.GetExtensions()) { mergeListener.PostMerge(cudResult, objRefs); } if (originalRefs != null) { // Set each original ref to null in order to suppress a post-processing in a potentially calling IMergeProcess for (int a = originalRefs.Count; a-- > 0;) { originalRefs[a] = null; } } // TODO DCE must be fired HERE <--- return(oriCollection); }
protected IOriCollection MergeIntern(ICUDResult cudResultOriginal, IMethodDescription methodDescription) { IResultingBackgroundWorkerDelegate <IOriCollection> runnable = new IResultingBackgroundWorkerDelegate <IOriCollection>(delegate() { IDisposableCache childCache = CacheFactory.CreatePrivileged(CacheFactoryDirective.SubscribeTransactionalDCE, false, false, "MergeServiceRegistry.STATE"); try { IncrementalMergeState state = null; ICUDResult cudResultOfCache; if (MergeProcess.IsAddNewlyPersistedEntities() || (Log.DebugEnabled && CudResultPrinter != null)) { childCache = CacheFactory.CreatePrivileged(CacheFactoryDirective.SubscribeTransactionalDCE, false, false, "MergeServiceRegistry.STATE"); state = (IncrementalMergeState)CudResultApplier.AcquireNewState(childCache); cudResultOfCache = CudResultApplier.ApplyCUDResultOnEntitiesOfCache(cudResultOriginal, true, state); } else { cudResultOfCache = cudResultOriginal; } if (Log.DebugEnabled) { if (CudResultPrinter != null) { Log.Debug("Initial merge [" + RuntimeHelpers.GetHashCode(state) + "]:\n" + CudResultPrinter.PrintCUDResult(cudResultOfCache, state)); } else { Log.Debug("Initial merge [" + RuntimeHelpers.GetHashCode(state) + "]. No Details available"); } } List <MergeOperation> mergeOperationSequence = new List <MergeOperation>(); ICUDResult extendedCudResult = WhatIfMerged(cudResultOfCache, methodDescription, mergeOperationSequence, state); if (Log.DebugEnabled) { Log.Debug("Merge finished [" + RuntimeHelpers.GetHashCode(state) + "]"); } if (MergeSecurityManager != null) { SecurityActive.ExecuteWithSecurityDirective(SecurityDirective.ENABLE_ENTITY_CHECK, delegate() { MergeSecurityManager.CheckMergeAccess(extendedCudResult, methodDescription); }); } List <Object> originalRefsOfCache = new List <Object>(cudResultOfCache.GetOriginalRefs()); List <Object> originalRefsExtended = new List <Object>(extendedCudResult.GetOriginalRefs()); IOriCollection oriCollExtended = Intern(extendedCudResult, methodDescription, mergeOperationSequence, state); IList <IChangeContainer> allChangesOriginal = cudResultOriginal.AllChanges; IList <IObjRef> allChangedObjRefsExtended = oriCollExtended.AllChangeORIs; IObjRef[] allChangedObjRefsResult = new IObjRef[allChangesOriginal.Count]; IdentityHashMap <Object, int?> originalRefOfCacheToIndexMap = new IdentityHashMap <Object, int?>(); for (int a = originalRefsOfCache.Count; a-- > 0;) { originalRefOfCacheToIndexMap.Put(originalRefsOfCache[a], a); } for (int a = originalRefsExtended.Count; a-- > 0;) { int?indexOfCache = originalRefOfCacheToIndexMap.Get(originalRefsExtended[a]); if (indexOfCache == null) { // this is a change implied by a rule or an persistence-implicit change // we do not know about it in the outer original CUDResult continue; } IObjRef objRefExtended = allChangedObjRefsExtended[a]; IObjRef objRefOriginal = allChangesOriginal[indexOfCache.Value].Reference; if (objRefExtended == null) { // entity has been deleted objRefOriginal.Id = null; objRefOriginal.Version = null; } else { objRefOriginal.Id = objRefExtended.Id; objRefOriginal.Version = objRefExtended.Version; } if (objRefOriginal is IDirectObjRef) { ((IDirectObjRef)objRefOriginal).Direct = null; } allChangedObjRefsResult[indexOfCache.Value] = objRefOriginal; } OriCollection oriCollection = new OriCollection(new List <IObjRef>(allChangedObjRefsResult)); return(oriCollection); } finally { childCache.Dispose(); } }); if (SecurityActive == null || !SecurityActive.FilterActivated) { return(runnable()); } else { return(SecurityActive.ExecuteWithoutFiltering(runnable)); } }
public IOriCollection Merge(ICUDResult cudResult, IMethodDescription methodDescription) { return(null); }
public IOriCollection Merge(ICUDResult cudResult, IMethodDescription methodDescription) { int localDcId; IDataChange dataChange; IList <IChangeContainer> allChanges = cudResult.AllChanges; IList <IObjRef> resultOriList = new List <IObjRef>(allChanges.Count); String changedBy = "anonymous"; long changedOn; Lock writeLock = PersistenceMock.GetWriteLock(); writeLock.Lock(); try { localDcId = ++dcId; changedOn = DateTimeUtil.CurrentTimeMillis(); IList <IDataChangeEntry> inserts = new List <IDataChangeEntry>(); IList <IDataChangeEntry> updates = new List <IDataChangeEntry>(); IList <IDataChangeEntry> deletes = new List <IDataChangeEntry>(); for (int a = 0, size = allChanges.Count; a < size; a++) { IChangeContainer changeContainer = allChanges[a]; IObjRef reference = changeContainer.Reference; if (changeContainer is DeleteContainer) { PersistenceMock.RemoveObject(reference); resultOriList.Add(null); deletes.Add(new DataChangeEntry(reference.RealType, reference.IdNameIndex, reference.Id, reference.Version)); } else if (changeContainer is UpdateContainer) { resultOriList.Add(reference); reference.Version = ((int)reference.Version) + 1; PersistenceMock.ChangeObject(reference, ((UpdateContainer)changeContainer).Primitives, ((UpdateContainer)changeContainer).Relations, changedBy, changedOn); updates.Add(new DataChangeEntry(reference.RealType, reference.IdNameIndex, reference.Id, reference.Version)); } else if (changeContainer is CreateContainer) { Object newId = AcquireIdForEntityType(reference.RealType); if (newId == null) { throw new Exception("Id must be valid"); } IEntityMetaData metaData = EntityMetaDataProvider.GetMetaData(reference.RealType); newId = ConversionHelper.ConvertValueToType(metaData.IdMember.ElementType, newId); reference.Id = newId; reference.Version = 1; ((IDirectObjRef)reference).Direct = null; resultOriList.Add(reference); PersistenceMock.AddObject(reference, ((CreateContainer)changeContainer).Primitives, ((CreateContainer)changeContainer).Relations, changedBy, changedOn); inserts.Add(new DataChangeEntry(reference.RealType, ObjRef.PRIMARY_KEY_INDEX, reference.Id, reference.Version)); } } OriCollection oriColl = new OriCollection(resultOriList); oriColl.ChangedBy = changedBy; oriColl.ChangedOn = changedOn; MergeController.ApplyChangesToOriginals(cudResult, oriColl, null); dataChange = new DataChangeEvent(inserts, updates, deletes, DateTimeUtil.ConvertJavaMillisToDateTime(changedOn), false); } finally { writeLock.Unlock(); } EventDispatcher.DispatchEvent(dataChange, dataChange.ChangeTime, localDcId); OriCollection oriCollection = new OriCollection(resultOriList); oriCollection.ChangedBy = changedBy; oriCollection.ChangedOn = changedOn; return(oriCollection); }
public virtual IOriCollection Merge(ICUDResult cudResult, IMethodDescription methodDescription) { return(MergeServiceWCF.Merge((CUDResult)cudResult, (MethodDescription)methodDescription)); }
public void AddOperationDescription(IMethodDescription method) { _operations.Add(method); }