private (TService, Mock <TestCallInvoker>) CreateServiceInstance <TService>() where TService : class { var(moduleBuilder, definedTypes) = this.CreateModuleBuilder(); var proxyBuilder = new RpcServiceProxyBuilder <GrpcProxyBase, GrpcProxyMethod>(RpcBuilderUtil.GetAllServices <TService>(true), moduleBuilder, definedTypes); var(proxyType, proxyMethods) = proxyBuilder.BuildObjectProxyType(new Type[] { typeof(GrpcProxyArgs), typeof(GrpcProxyMethod[]) }); ValidateProxyType <TService>(proxyType); var factory = RpcServiceProxyBuilder <GrpcProxyBase, GrpcProxyMethod> .CreateObjectProxyFactory <GrpcProxyArgs>(proxyType); var callInvokerMock = new Mock <TestCallInvoker>(MockBehavior.Strict); var connectionMock = new Mock <IRpcConnection>(MockBehavior.Strict); connectionMock.Setup(m => m.Options).Returns(ImmutableRpcClientOptions.Empty); var serializer = new ProtobufRpcSerializer(); var args = new GrpcProxyArgs ( objectId: RpcObjectId.NewId(), connection: connectionMock.Object, callInvoker: callInvokerMock.Object, serializer: serializer, methodsCache: new GrpcMethodsCache(serializer), implementedServices: null, syncContext: null ); var serviceInstance = factory(args, proxyMethods); return((TService)(object)serviceInstance, callInvokerMock); }
public IOwned <RpcObjectRef <TService> > PublishInstance <TService>(IOwned <TService> serviceInstance) where TService : class { if (serviceInstance is null) { throw new ArgumentNullException(nameof(serviceInstance)); } var allServices = RpcBuilderUtil.GetAllServices(serviceInstance.Value.GetType(), true); this.TryRegisterServiceDefinitions(allServices, null); var connectionInfo = this.RetrieveConnectionInfo(); lock (this.syncRoot) { var serviceInstanceId = RpcObjectId.NewId(); var publishedServices = this.PublishInstanceCore_Locked(allServices, serviceInstance, serviceInstanceId, false); Func <ValueTask> disposeAction = () => this.UnpublishInstanceAsync(serviceInstanceId); return(OwnedObject.Create(new RpcObjectRef <TService>( connectionInfo, serviceInstanceId, publishedServices.ToArray()), disposeAction)); } }
public async Task UnavailableService_ShouldThrowRpcServiceUnavailableException(TestOperationType operationType) { var serviceRegistrator = new RpcServiceDefinitionsBuilder(); serviceRegistrator .RegisterService <IBlockingService>() .RegisterService <ISimpleService>(); var(host, connection) = this.CreateServerAndConnection(serviceRegistrator); using (var publishedInstanceScope = host.ServicePublisher.PublishInstance <IBlockingService>(new TestBlockingServiceImpl())) { var objectId = RpcObjectId.NewId(); var blockingClientService = connection.GetServiceInstance <IBlockingServiceClient>(objectId); var simpleService = connection.GetServiceInstance <ISimpleService>(objectId); host.Start(); try { // Invoke unknown service instance switch (operationType) { case TestOperationType.BlockingBlocking: Assert.Throws <RpcServiceUnavailableException>(() => blockingClientService.Add(12, 13)); break; case TestOperationType.AsyncBlocking: // Async/blocking (client/host) Assert.ThrowsAsync <RpcServiceUnavailableException>(() => blockingClientService.AddAsync(12, 13)); break; case TestOperationType.BlockingBlockingVoid: Assert.Throws <RpcServiceUnavailableException>(() => blockingClientService.Value = 23); break; case TestOperationType.AsyncBlockingVoid: // Async/blocking void (client/host) Assert.ThrowsAsync <RpcServiceUnavailableException>(() => blockingClientService.SetValueAsync(13)); break; case TestOperationType.AsyncAsync: // Async/async (client/host) Assert.ThrowsAsync <RpcServiceUnavailableException>(() => simpleService.AddAsync(12, 13)); break; case TestOperationType.AsyncAsyncVoid: // Async/async void (client/host) Assert.ThrowsAsync <RpcServiceUnavailableException>(() => simpleService.SetValueAsync(12)); break; } var exisingService = connection.GetServiceInstance <IBlockingServiceClient>(publishedInstanceScope.Value); // Make sure that the connection is still usable after exception Assert.AreEqual(12 + 13, exisingService.Add(12, 13)); } finally { await host.ShutdownAsync(); } } }
public async Task EmptyDerivedProxyTest() { var(serviceInstance, callInvokerMock) = CreateServiceInstance <IEmptyDerivedService>(); RpcObjectId objectId = ((IRpcProxy)serviceInstance).ObjectId; // Test Add and Sub, defined on different interfaces callInvokerMock.Setup(p => p.UnaryFunc <RpcObjectRequest <int, int>, RpcResponse <int> >("Add", It.IsAny <RpcObjectRequest <int, int> >())) .Returns((string op, RpcObjectRequest <int, int> r) => { Assert.AreEqual(objectId, r.Id); return(new RpcResponse <int> { Result = r.Value1 + r.Value2 }); }); var addRes = await serviceInstance.AddAsync(18, 19); Assert.AreEqual(18 + 19, addRes); callInvokerMock.Setup(p => p.UnaryFunc <RpcObjectRequest <int, int>, RpcResponse <int> >("Sub", It.IsAny <RpcObjectRequest <int, int> >())) .Returns((string op, RpcObjectRequest <int, int> r) => { Assert.AreEqual(objectId, r.Id); return(new RpcResponse <int> { Result = r.Value1 - r.Value2 }); }); var subRes = await serviceInstance.SubAsync(1218, 119); Assert.AreEqual(1218 - 119, subRes); }
public async Task GenerateSimpleServiceStubTest() { var binder = new TestLightweightMethodBinder(); CreateSimpleServiceStub <ISimpleService>(new TestSimpleServiceImpl(), binder); LightweightMethodStub addStub = binder.GetHandler <RpcObjectRequest <int, int>, RpcResponse <int> >("SciTech.Rpc.Tests.SimpleService.Add"); Assert.NotNull(addStub); var objectId = RpcObjectId.NewId(); var request = new RpcObjectRequest <int, int>(objectId, 5, 6); RpcResponse <int> addResponse = await LightweightStubHelper.SendReceiveAsync <RpcObjectRequest <int, int>, RpcResponse <int> >(addStub, request, DefaultSerializer); Assert.AreEqual(11, addResponse.Result); LightweightMethodStub setStub = binder.GetHandler <RpcObjectRequest <double>, RpcResponse>("SciTech.Rpc.Tests.SimpleService.SetValue"); Assert.NotNull(setStub); var setResponse = await LightweightStubHelper.SendReceiveAsync <RpcObjectRequest <double>, RpcResponse>(setStub, new RpcObjectRequest <double>(objectId, 20), DefaultSerializer); Assert.NotNull(setResponse); LightweightMethodStub getStub = binder.GetHandler <RpcObjectRequest, RpcResponse <double> >("SciTech.Rpc.Tests.SimpleService.GetValue"); Assert.NotNull(getStub); var getResponse = await LightweightStubHelper.SendReceiveAsync <RpcObjectRequest, RpcResponse <double> >(getStub, new RpcObjectRequest(objectId), DefaultSerializer); Assert.AreEqual(20, getResponse.Result); }
public static void UnpublishInstance(this IRpcServer server, RpcObjectId serviceInstanceId) { if (server is null) { throw new ArgumentNullException(nameof(server)); } server.ServicePublisher.UnpublishInstance(serviceInstanceId); }
public static void UnpublishInstance(this IRpcServicePublisher publisher, RpcObjectId serviceInstanceId) { if (publisher is null) { throw new ArgumentNullException(nameof(publisher)); } publisher.UnpublishInstanceAsync(serviceInstanceId).AsTask().AwaiterResult(); }
public RpcProxyArgs( IRpcChannel connection, RpcObjectId objectId, IRpcSerializer serializer, IReadOnlyCollection <string>?implementedServices, SynchronizationContext?syncContext) { this.Channel = connection ?? throw new ArgumentNullException(nameof(connection)); this.ObjectId = objectId; this.Serializer = serializer; this.ImplementedServices = implementedServices; this.SyncContext = syncContext; }
internal GrpcProxyArgs(IRpcChannel connection, GrpcCore.CallInvoker callInvoker, RpcObjectId objectId, GrpcMethodsCache methodsCache, IRpcSerializer serializer, IReadOnlyCollection <string>?implementedServices, SynchronizationContext?syncContext) : base(connection, objectId, serializer, implementedServices, syncContext) { this.CallInvoker = callInvoker; this.MethodsCache = methodsCache; }
/// <inheritdoc/> public TService GetServiceInstance <TService>( RpcObjectId objectId, IReadOnlyCollection <string>?implementedServices, SynchronizationContext?syncContext) where TService : class { if (objectId == RpcObjectId.Empty) { throw new ArgumentException("ObjectId should not be empty.", nameof(objectId)); } return(GetServiceInstanceCore <TService>(objectId, implementedServices, syncContext)); }
public ImmutableArray <string> GetPublishedServices(RpcObjectId objectId) { lock (this.syncRoot) { if (this.idToPublishedServices.TryGetValue(objectId, out var servicesList)) { return(servicesList.ServiceNames); } return(ImmutableArray <string> .Empty); } }
private TService GetServiceInstanceCore <TService>( RpcObjectId refObjectId, IReadOnlyCollection <string>?implementedServices, SynchronizationContext?syncContext) where TService : class { lock (this.SyncRoot) { if (this.serviceInstances.TryGetValue(refObjectId, out var servicesList)) { foreach (var wService in servicesList) { if (wService.TryGetTarget(out var proxyBase) && proxyBase is TService service && proxyBase.SyncContext == syncContext && proxyBase.ImplementsServices(implementedServices)) { return(service); } } } } RpcObjectProxyFactory serviceProxyCreator = this.proxyGenerator.GenerateObjectProxyFactory <TService>(implementedServices, this.Options.KnownServiceTypesDictionary); lock (this.SyncRoot) { if (this.serviceInstances.TryGetValue(refObjectId, out var servicesList)) { foreach (var wService in servicesList) { if (wService.TryGetTarget(out var proxyBase) && proxyBase is TService service && proxyBase.SyncContext == syncContext && proxyBase.ImplementsServices(implementedServices)) { return(service); } } } else { servicesList = new List <WeakReference <RpcProxyBase> >(); this.serviceInstances.Add(refObjectId, servicesList); } var serviceInstance = serviceProxyCreator(refObjectId, this, syncContext); servicesList.Add(new WeakReference <RpcProxyBase>(serviceInstance)); return((TService)(object)serviceInstance); } }
internal LightweightProxyArgs( LightweightRpcConnection connection, IReadOnlyList <RpcClientCallInterceptor> callInterceptors, RpcObjectId objectId, IRpcSerializer serializer, LightweightSerializersCache methodSerializersCache, IReadOnlyCollection <string>?implementedServices, SynchronizationContext?syncContext) : base(connection, objectId, serializer, implementedServices, syncContext) { this.MethodSerializersCache = methodSerializersCache; this.CallInterceptors = callInterceptors; }
public void HostNotFoundTest() { var serviceRegistrator = new RpcServiceDefinitionsBuilder(); serviceRegistrator .RegisterService <IBlockingService>();; var(_, connection) = this.CreateServerAndConnection(serviceRegistrator); var objectId = RpcObjectId.NewId(); var clientService = connection.GetServiceInstance <IBlockingServiceClient>(objectId); // Invoke client operation without starting host Assert.Throws <RpcCommunicationException>(() => clientService.Add(12, 13)); }
public async Task SimpleProxyTest() { var(serviceInstance, callInvokerMock) = CreateServiceInstance <ISimpleService>(); RpcObjectId objectId = ((IRpcProxy)serviceInstance).ObjectId; callInvokerMock.Setup(p => p.UnaryFunc <RpcObjectRequest <int, int>, RpcResponse <int> >("Add", It.IsAny <RpcObjectRequest <int, int> >())) .Returns((string op, RpcObjectRequest <int, int> r) => { Assert.AreEqual(objectId, r.Id); return(new RpcResponse <int> { Result = r.Value1 + r.Value2 }); }); var m = serviceInstance.GetType().GetMethod("SimpleService.AddAsync", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); var mb = m.GetMethodBody(); var il = mb.GetILAsByteArray(); var res = await serviceInstance.AddAsync(5, 6); Assert.AreEqual(11, res); callInvokerMock.Setup(p => p.UnaryFunc <RpcObjectRequest <double>, RpcResponse>("SetValue", It.IsAny <RpcObjectRequest <double> >())) .Returns((string op, RpcObjectRequest <double> r) => { Assert.AreEqual(objectId, r.Id); Assert.AreEqual(123.45, r.Value1); return(new RpcResponse()); }); await serviceInstance.SetValueAsync(123.45); callInvokerMock.Setup(p => p.UnaryFunc <RpcObjectRequest, RpcResponse <double> >("GetValue", It.IsAny <RpcObjectRequest>())) .Returns((string op, RpcObjectRequest r) => { Assert.AreEqual(objectId, r.Id); return(new RpcResponse <double> { Result = 543.21 }); }); var getRes = await serviceInstance.GetValueAsync(); Assert.AreEqual(543.21, getRes); }
public async Task SimpleServiceSetGetStubTest() { var binder = new TestMethodBinder(); CreateSimpleServiceStub <ISimpleService>(new TestSimpleServiceImpl(), binder); var callContext = CreateServerCallContext(CancellationToken.None); var objectId = RpcObjectId.NewId(); var setHandler = binder.GetHandler <UnaryServerMethod <RpcObjectRequest <double>, RpcResponse> >("SetValue"); await setHandler(new RpcObjectRequest <double>(objectId, 123.456), callContext); var getHandler = binder.GetHandler <UnaryServerMethod <RpcObjectRequest, RpcResponse <double> > >("GetValue"); var getResponse = await getHandler(new RpcObjectRequest(objectId), callContext); Assert.AreEqual(123.456, getResponse.Result); }
public ValueTask UnpublishInstanceAsync(RpcObjectId serviceInstanceId) { PublishedInstance?removedInstance = null; lock (this.syncRoot) { if (this.idToPublishedServices.TryGetValue(serviceInstanceId, out var publishedServices)) { foreach (var serviceType in publishedServices.ServiceTypes) { var serviceKey = new ServiceImplKey(serviceInstanceId, serviceType); if (this.idToServiceImpl.TryGetValue(serviceKey, out var publishedInstance)) { this.idToServiceImpl.Remove(serviceKey); if (removedInstance == null) { removedInstance = publishedInstance; } else { Debug.Assert(Equals(removedInstance, publishedInstance)); } } this.idToServiceFactory.Remove(serviceKey); } } if (removedInstance != null) { var instance = removedInstance.Value.GetInstance(); if (instance != null) { this.serviceImplToId.Remove(new InstanceKey(instance)); } } } if (removedInstance?.GetOwnedInstance() is IAsyncDisposable disposable) { return(disposable.DisposeAsync()); } return(default);
public async Task GenerateSimpleServiceStubTest() { var binder = new TestMethodBinder(); CreateSimpleServiceStub <ISimpleService>(new TestSimpleServiceImpl(), binder); var callContext = CreateServerCallContext(CancellationToken.None); var addHandler = binder.GetHandler <GrpcCore.UnaryServerMethod <RpcObjectRequest <int, int>, RpcResponse <int> > >("Add"); Assert.NotNull(addHandler); var objectId = RpcObjectId.NewId(); var addResponseTask = addHandler.Invoke(new RpcObjectRequest <int, int>(objectId, 5, 6), callContext); var response = await addResponseTask.DefaultTimeout(); Assert.AreEqual(11, response.Result); }
public void BlockingProxyTest() { var(serviceInstance, callInvokerMock) = CreateServiceInstance <IBlockingService>(); RpcObjectId objectId = ((IRpcProxy)serviceInstance).ObjectId; callInvokerMock.Setup(p => p.UnaryFunc <RpcObjectRequest <int, int>, RpcResponse <int> >("Add", It.IsAny <RpcObjectRequest <int, int> >())) .Returns((string op, RpcObjectRequest <int, int> r) => { Assert.AreEqual(objectId, r.Id); return(new RpcResponse <int> { Result = r.Value1 + r.Value2 }); }); var res = serviceInstance.Add(5, 6); Assert.AreEqual(11, res); callInvokerMock.Setup(p => p.UnaryFunc <RpcObjectRequest <double>, RpcResponse>("SetValue", It.IsAny <RpcObjectRequest <double> >())) .Returns((string op, RpcObjectRequest <double> r) => { Assert.AreEqual(objectId, r.Id); Assert.AreEqual(123.45, r.Value1); return(new RpcResponse()); }); serviceInstance.Value = 123.45; callInvokerMock.Setup(p => p.UnaryFunc <RpcObjectRequest, RpcResponse <double> >("GetValue", It.IsAny <RpcObjectRequest>())) .Returns((string op, RpcObjectRequest r) => { Assert.AreEqual(objectId, r.Id); return(new RpcResponse <double> { Result = 543.21 }); }); var getRes = serviceInstance.Value; Assert.AreEqual(543.21, getRes); }
public IOwned <RpcObjectRef <TService> > PublishInstance <TService>(Func <IServiceProvider?, RpcObjectId, IOwned <TService> > factory) where TService : class { var allServices = RpcBuilderUtil.GetAllServices(typeof(TService), RpcServiceDefinitionSide.Server, true); this.TryRegisterServiceDefinitions(allServices, null); var connectionInfo = this.RetrieveConnectionInfo(); lock (this.syncRoot) { var objectId = RpcObjectId.NewId(); var publishedServices = this.PublishInstanceFactoryCore_Locked(allServices, objectId, factory); return(OwnedObject.Create(new RpcObjectRef <TService>( connectionInfo, objectId, publishedServices.ToArray()), () => this.UnpublishInstanceAsync(objectId))); } }
public async Task BlockingStubTest() { // TODO: Should use a mock instead. var serviceImpl = new TestBlockingSimpleServiceImpl(); var binder = new TestMethodBinder(); CreateSimpleServiceStub <IBlockingService>(serviceImpl, binder); var callContext = CreateServerCallContext(CancellationToken.None); var objectId = RpcObjectId.NewId(); var setMethod = binder.methods.FirstOrDefault(p => p.Item1.Name == "SetValue"); Assert.NotNull(setMethod); var setValueHandler = (UnaryServerMethod <RpcObjectRequest <double>, RpcResponse>)setMethod.Item2; await setValueHandler(new RpcObjectRequest <double>(objectId, 123.456), callContext); //await (Task<RpcResponse>)setMethod.Invoke(serviceStub, new object[] { new RpcObjectRequest<double>(objectId, 123.456), callContext }); Assert.AreEqual(1, serviceImpl.nBlockingSetValue); var getMethod = binder.methods.FirstOrDefault(p => p.Item1.Name == "GetValue"); Assert.NotNull(getMethod); var getValueHandler = (UnaryServerMethod <RpcObjectRequest, RpcResponse <double> >)getMethod.Item2; var getResponse = await getValueHandler(new RpcObjectRequest(objectId), callContext); Assert.AreEqual(1, serviceImpl.nBlockingGetValue); Assert.AreEqual(123.456, getResponse.Result); var addMethod = binder.methods.FirstOrDefault(p => p.Item1.Name == "Add"); var addHandler = (UnaryServerMethod <RpcObjectRequest <int, int>, RpcResponse <int> >)addMethod.Item2; var addResponse = await addHandler(new RpcObjectRequest <int, int>(objectId, 8, 9), callContext); Assert.AreEqual(1, serviceImpl.nBlockingAdd); Assert.AreEqual(17, addResponse.Result); }
public RpcObjectRef <TService> GetOrPublishInstance <TService>(TService serviceInstance) where TService : class { if (serviceInstance is null) { throw new ArgumentNullException(nameof(serviceInstance)); } InstanceKey key; lock (this.syncRoot) { key = new InstanceKey(serviceInstance); if (this.serviceImplToId.TryGetValue(key, out var instanceId)) { return(new RpcObjectRef <TService>(this.connectionInfo, instanceId, this.GetPublishedServices(instanceId).ToArray())); } } // Not published, so we try to register the serviceInstance's service definitions // and then publish it. var allServices = RpcBuilderUtil.GetAllServices(serviceInstance.GetType(), true); this.TryRegisterServiceDefinitions(allServices, null); var connectionInfo = this.RetrieveConnectionInfo(); lock (this.syncRoot) { // Let's try again. if (this.serviceImplToId.TryGetValue(key, out var instanceId)) { // Somebody beat us to it. return(new RpcObjectRef <TService>(this.connectionInfo, instanceId, this.GetPublishedServices(instanceId).ToArray())); } var objectId = RpcObjectId.NewId(); var newPublishedServices = this.PublishInstanceCore_Locked(allServices, OwnedObject.CreateUnowned(serviceInstance), objectId, true); return(new RpcObjectRef <TService>(connectionInfo, objectId, newPublishedServices.ToArray())); } }
public async Task DeviceServiceTest() { var serviceImpl = new ThermostatServiceImpl(); var implProviderMock = new Mock <IRpcServiceActivator>(); implProviderMock.Setup(p => p.GetActivatedService <IDeviceService>(It.IsAny <IServiceProvider>(), It.IsAny <RpcObjectId>())).Returns(new ActivatedService <IDeviceService>(serviceImpl, null)); var callContext = CreateServerCallContext(CancellationToken.None); var binder = new TestMethodBinder(); CreateSimpleServiceStub <IDeviceService>(serviceImpl, binder); var objectId = RpcObjectId.NewId(); var getMethod = binder.methods.FirstOrDefault(p => p.Item1.Name == "GetDeviceAcoId"); Assert.NotNull(getMethod); var getValueHandler = (UnaryServerMethod <RpcObjectRequest, RpcResponse <Guid> >)getMethod.Item2; var getResponse = await getValueHandler(new RpcObjectRequest(objectId), callContext); Assert.AreEqual(serviceImpl.DeviceAcoId, getResponse.Result); }
internal RpcObjectRef(RpcConnectionInfo?connectionInfo, RpcObjectId objectId, string[]?implementedServices) { this.ServerConnection = connectionInfo; this.ObjectId = objectId; this.ImplementedServices = implementedServices; }
public async Task EventHandlersTest() { var(serviceInstance, callInvokerMock) = CreateServiceInstance <ISimpleServiceWithEvents>(); RpcObjectId objectId = ((IRpcProxy)serviceInstance).ObjectId; callInvokerMock.Setup(p => p.ServerStreamingFunc <RpcObjectRequest, EventArgs>(It.IsAny <string>(), It.IsAny <RpcObjectRequest>(), It.IsAny <CancellationToken>())) .Returns((string op, RpcObjectRequest r, CancellationToken ct) => { Assert.AreEqual(objectId, r.Id); return(new AsyncStreamReader <EventArgs>(() => (EventArgs.Empty, true), 0, 20, ct)); }); int currValue = 4; callInvokerMock.Setup(p => p.ServerStreamingFunc <RpcObjectRequest, ValueChangedEventArgs>(It.IsAny <string>(), It.IsAny <RpcObjectRequest>(), It.IsAny <CancellationToken>())) .Returns((string op, RpcObjectRequest r, CancellationToken ct) => { Assert.AreEqual(objectId, r.Id); return(new AsyncStreamReader <ValueChangedEventArgs>(() => { var oldValue = currValue++; return (new ValueChangedEventArgs(currValue, oldValue), true); }, 10, 10, ct));; }); //callInvokerMock.Setup(p => p.UnaryFunc<RpcObjectEventRequest, RpcResponse>("EndEventProducer", It.IsAny<RpcObjectEventRequest>())) // .Returns(()=>new RpcResponse()); int simpleChangeCount = 0; TaskCompletionSource <bool> simpleTcs = new TaskCompletionSource <bool>(); EventHandler eventHandler = (s, e) => { simpleChangeCount++; if (simpleChangeCount == 2) { simpleTcs.SetResult(true); } }; int?expectedOldValue = null; int detailedChangeCount = 0; TaskCompletionSource <bool> detailedTcs = new TaskCompletionSource <bool>(); EventHandler <ValueChangedEventArgs> detailedEventHandler = (s, e) => { if (expectedOldValue != null) { Assert.AreEqual(expectedOldValue.Value, e.OldValue); } Assert.AreEqual(e.OldValue + 1, e.NewValue); expectedOldValue = e.NewValue; detailedChangeCount++; if (detailedChangeCount == 3) { detailedTcs.SetResult(true); } }; serviceInstance.ValueChanged += eventHandler; await((IRpcProxy)serviceInstance).WaitForPendingEventHandlersAsync(); serviceInstance.DetailedValueChanged += detailedEventHandler; await Task.WhenAny(Task.WhenAll(simpleTcs.Task, detailedTcs.Task), Task.Delay(1000)); Assert.AreEqual(TaskStatus.RanToCompletion, simpleTcs.Task.Status); Assert.AreEqual(TaskStatus.RanToCompletion, detailedTcs.Task.Status); serviceInstance.ValueChanged -= eventHandler; serviceInstance.DetailedValueChanged -= detailedEventHandler; // TODO: Assert that Remove event method has been called for both handlers. }
public void IncorrectServiceFault_ShouldThrowDefinitionException() { var serviceRegistrator = new RpcServiceDefinitionsBuilder(); var(_, connection) = this.CreateServerAndConnection(serviceRegistrator); Assert.Throws <RpcDefinitionException>(() => connection.GetServiceInstance <IIncorrectServiceFaultServiceClient>(RpcObjectId.NewId())); }
public void Clear() { this.Id = default; }
public RpcObjectRequest(RpcObjectId id) { this.Id = id; }
public async Task EventHandlerTest() { var serviceImpl = new TestServiceWithEventsImpl(); var binder = new TestMethodBinder(); CreateSimpleServiceStub <ISimpleServiceWithEvents>(serviceImpl, binder); var beginHandler = binder.GetHandler <GrpcCore.ServerStreamingServerMethod <RpcObjectRequest, EventArgs> >("BeginValueChanged"); var objectId = RpcObjectId.NewId(); //var valueChangedMethod = stubType.GetMethod($"Begin{nameof(IServiceWithEvents.ValueChanged)}"); var valueChangedStreamWriter = new ServerEventStreamWriter <EventArgs>(10); CancellationTokenSource eventListerCancellationSource = new CancellationTokenSource(); var callContext = CreateServerCallContext(eventListerCancellationSource.Token); Task valueChangedTask = beginHandler(new RpcObjectRequest(objectId), valueChangedStreamWriter, callContext); var detailedValueChangedStreamWriter = new ServerEventStreamWriter <ValueChangedEventArgs>(10); var beginDetailedHandler = binder.GetHandler <GrpcCore.ServerStreamingServerMethod <RpcObjectRequest, ValueChangedEventArgs> >("BeginDetailedValueChanged"); CancellationTokenSource detailedEventListerCancellationSource = new CancellationTokenSource(); var detailedCallContext = CreateServerCallContext(detailedEventListerCancellationSource.Token); Task detailedValueChangedTask = beginDetailedHandler(new RpcObjectRequest(objectId), detailedValueChangedStreamWriter, detailedCallContext); await Task.WhenAny(Task.WhenAll(valueChangedStreamWriter.StartedTask, detailedValueChangedStreamWriter.StartedTask), Task.Delay(5000)); Assert.IsTrue(valueChangedStreamWriter.StartedTask.IsCompletedSuccessfully()); Assert.IsTrue(detailedValueChangedStreamWriter.StartedTask.IsCompletedSuccessfully()); Task.Run(async() => { List <Task> tasks = new List <Task>(); for (int i = 0; i < 20; i++) { tasks.Add(serviceImpl.SetValueAsync(18 + i)); } await Task.WhenAll(tasks); } ).Forget(); await Task.WhenAny(Task.WhenAll(valueChangedStreamWriter.CompletedTask, detailedValueChangedStreamWriter.CompletedTask), Task.Delay(5000)); Assert.IsTrue(valueChangedStreamWriter.CompletedTask.IsCompletedSuccessfully()); Assert.IsTrue(detailedValueChangedStreamWriter.CompletedTask.IsCompletedSuccessfully()); eventListerCancellationSource.Cancel(); detailedEventListerCancellationSource.Cancel(); //var endProducerHandler = binder.GetHandler<GrpcCore.UnaryServerMethod<RpcObjectEventRequest, RpcResponse>>(nameof(RpcStub<object>.EndEventProducer)); //var endTask = endProducerHandler(new RpcObjectEventRequest(objectId, eventProducerId), callContext); //var endDetailedTask = endProducerHandler(new RpcObjectEventRequest(objectId, detailedEventProducerId), callContext); //await Task.WhenAll(endTask, endDetailedTask); try { await Task.WhenAll(valueChangedTask, detailedValueChangedTask); } catch (OperationCanceledException) { } Assert.IsTrue(valueChangedTask.IsCompletedSuccessfully() || valueChangedTask.IsCanceled); Assert.IsTrue(detailedValueChangedTask.IsCompletedSuccessfully() || detailedValueChangedTask.IsCanceled); Assert.GreaterOrEqual(valueChangedStreamWriter.GetMessages().Length, 10); // Too timing dependent //Assert.Less(valueChangedStreamWriter.GetMessages().Length, 20); var detailedMessages = detailedValueChangedStreamWriter.GetMessages(); Assert.GreaterOrEqual(detailedMessages.Length, 10); // Too timing dependent //Assert.Less(detailedValueChangedStreamWriter.GetMessages().Length, 20); int oldValue = 0; int newValue = 18; for (int i = 0; i < 10; i++) { var msg = detailedMessages[i]; Assert.AreEqual(oldValue, msg.OldValue); Assert.AreEqual(newValue, msg.NewValue); oldValue = msg.NewValue; newValue = oldValue + 1; } }
/// <summary> /// Gets a proxy to the service instance specified by <paramref name="objectId"/>. /// </summary> /// <typeparam name="TService"></typeparam> /// <param name="objectId"></param> /// <param name="useSyncContext">Indicates that the current synchronization context should be used for the service intance.</param> /// <returns>The service proxy.</returns> /// <exception cref="RpcDefinitionException">Thrown if the RPC definition of <typeparamref name="TService"/> is not correct.</exception> public static TService GetServiceInstance <TService>(this IRpcChannel connection, RpcObjectId objectId, bool useSyncContext = true) where TService : class { if (connection is null) { throw new ArgumentNullException(nameof(connection)); } return(connection.GetServiceInstance <TService>(objectId, default, useSyncContext ? SynchronizationContext.Current : null));