示例#1
0
        public ListenerScanner(IReqResBus messageBus, ILogger logger)
        {
            Assert.ArgumentNotNull(messageBus, nameof(messageBus));

            _logger  = logger ?? messageBus.Logger;
            _builder = new UntypedListenerBuilder(messageBus);
        }
示例#2
0
        /// <summary>
        /// Setup round-robin distribution rules for Request/Response channels
        /// </summary>
        /// <typeparam name="TRequest"></typeparam>
        /// <typeparam name="TResponse"></typeparam>
        /// <param name="messageBus"></param>
        /// <param name="inTopics"></param>
        /// <param name="outTopics"></param>
        /// <returns></returns>
        public static IDisposable SetupRequestDistribution <TRequest, TResponse>(this IReqResBus messageBus, string inTopics, IEnumerable <string> outTopics)
        {
            Assert.ArgumentNotNull(messageBus, nameof(messageBus));
            var rule = new RoundRobinDistributeRule <TRequest>(outTopics);

            return(messageBus.RequestRouter.AddRequestRouteRule <TRequest, TResponse>(inTopics, rule));
        }
示例#3
0
        public ListenerBuilder(IReqResBus messageBus, IWorkerPool workerPool)
        {
            Assert.ArgumentNotNull(messageBus, nameof(messageBus));
            Assert.ArgumentNotNull(workerPool, nameof(workerPool));

            _messageBus = messageBus;
            _workerPool = workerPool;
        }
示例#4
0
        public static IRequest <TResponse> Request <TRequest, TResponse>(this IReqResBus messageBus, string topic, TRequest requestPayload)
        {
            Assert.ArgumentNotNull(messageBus, nameof(messageBus));

            var envelope = messageBus.EnvelopeFactory.Create(topic, requestPayload);

            return(messageBus.RequestEnvelope <TRequest, TResponse>(envelope));
        }
示例#5
0
        /// <summary>
        /// Setup rules to route the Request/Response channel by inspecting the contents of the request payload
        /// </summary>
        /// <typeparam name="TRequest"></typeparam>
        /// <typeparam name="TResponse"></typeparam>
        /// <param name="messageBus"></param>
        /// <param name="inTopic"></param>
        /// <param name="getTopic"></param>
        /// <returns></returns>
        public static IDisposable SetupRequestByExamination <TRequest, TResponse>(this IReqResBus messageBus, string inTopic, Func <TRequest, string> getTopic)
        {
            Assert.ArgumentNotNull(messageBus, nameof(messageBus));
            Assert.ArgumentNotNull(getTopic, nameof(getTopic));
            var rule = new PayloadExamineRule <TRequest>(getTopic);

            return(messageBus.RequestRouter.AddRequestRouteRule <TRequest, TResponse>(inTopic, rule));
        }
示例#6
0
        /// <summary>
        /// Build a listener to handle requests of the given type using common options.
        /// </summary>
        /// <typeparam name="TRequest">The type of the request object</typeparam>
        /// <typeparam name="TResponse">The type of the response object</typeparam>
        /// <param name="messageBus">The message bus</param>
        /// <param name="build">The lambda function to build the listener</param>
        /// <returns>A token representing the subscription whic, when disposed, cancels the subscription</returns>
        public static IDisposable Listen <TRequest, TResponse>(this IReqResBus messageBus, Action <ITopicListenerBuilder <TRequest, TResponse> > build)
        {
            Assert.ArgumentNotNull(messageBus, nameof(messageBus));
            var builder = new ListenerBuilder <TRequest, TResponse>(messageBus, messageBus.WorkerPool);

            build(builder);
            var listener = builder.BuildListener();
            var token    = messageBus.Listen(builder.Topic, listener);

            return(builder.WrapToken(token));
        }
示例#7
0
        /// <summary>
        /// Add predicate-based routing rules for Request/Response operations
        /// </summary>
        /// <typeparam name="TRequest"></typeparam>
        /// <typeparam name="TResponse"></typeparam>
        /// <param name="messageBus"></param>
        /// <param name="build"></param>
        /// <returns></returns>
        public static IDisposable SetupRequestRouting <TRequest, TResponse>(this IReqResBus messageBus, Action <IFilterRouteBuilderSingleInput <TRequest> > build)
        {
            Assert.ArgumentNotNull(messageBus, nameof(messageBus));
            Assert.ArgumentNotNull(build, nameof(build));

            var builder = new FilterRouteBuilder <TRequest>();

            build(builder);
            var router = builder.Build();

            return(messageBus.RequestRouter.AddRequestRouteRule <TRequest, TResponse>(builder.InTopics.FirstOrDefault(), router));
        }
        private static IDisposable BuildListener(IReqResBus messageBus, Func <TRequest, TResponse> func, Action <IThreadListenerBuilder <TRequest, TResponse> > build, string topic)
        {
            var token = messageBus.Listen <TRequest, TResponse>(b =>
            {
                var c = b
                        .WithTopic(topic)
                        .Invoke(func);
                build?.Invoke(c);
            });

            return(token);
        }
        public WrappedFunction <TRequest, TResponse> WrapFunction(IReqResBus messageBus, Func <TRequest, TResponse> func, Action <IThreadListenerBuilder <TRequest, TResponse> > build)
        {
            Assert.ArgumentNotNull(messageBus, nameof(messageBus));
            Assert.ArgumentNotNull(func, nameof(func));

            var topic = Guid.NewGuid().ToString();
            var token = BuildListener(messageBus, func, build, topic);

            var newFunc = BuildFunction(messageBus, topic);

            return(new WrappedFunction <TRequest, TResponse>(newFunc, token, topic));
        }
示例#10
0
        /// <summary>
        /// Make a request for cases where the type of request is not known until runtime. The bus
        /// attempts to infer the response type from metadata, and performs the request if possible.
        /// The request type must inherit from <see cref="IRequestWithResponse{TResponse}"/> in order to make
        /// the necessary type inferences.
        /// </summary>
        /// <param name="messageBus">The message bus</param>
        /// <param name="topic">The name of the channel</param>
        /// <param name="requestType">The runtime type of the request</param>
        /// <param name="request">The request object</param>
        /// <returns>The response object</returns>
        public static object Request(this IReqResBus messageBus, string topic, Type requestType, object request)
        {
            Assert.ArgumentNotNull(messageBus, nameof(messageBus));
            var requestInterface = requestType.GetInterfaces().FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IRequestWithResponse <>));

            if (requestInterface == null)
            {
                return(null);
            }

            var factoryMethod = messageBus.EnvelopeFactory.GetType()
                                .GetMethod(nameof(messageBus.EnvelopeFactory.Create))
                                .MakeGenericMethod(requestType);
            var envelope = factoryMethod.Invoke(messageBus.EnvelopeFactory, new[] { new [] { topic }, request, null });

            var responseType = requestInterface.GetGenericArguments().Single();

            var method = messageBus.GetType().GetMethod(nameof(messageBus.RequestEnvelope)).MakeGenericMethod(requestType, responseType);
            var waiter = (Request)method.Invoke(messageBus, new[] { envelope });

            waiter.WaitForResponse();
            waiter.ThrowExceptionIfError();
            return(waiter.GetResponseObject());
        }
        private static Func <TRequest, TResponse> BuildFunction(IReqResBus messageBus, string topic)
        {
            TResponse NewFunc(TRequest req) => messageBus.RequestWait <TRequest, TResponse>(topic, req);

            return(NewFunc);
        }
示例#12
0
        public static Task <TResponse> RequestAsync <TRequest, TResponse>(this IReqResBus messageBus, TRequest requestPayload)
        {
            var request = Request <TRequest, TResponse>(messageBus, requestPayload);

            return(request.GetResponseAsync());
        }
示例#13
0
 public static TResponse RequestWait <TRequest, TResponse>(this IReqResBus messageBus, TRequest requestPayload)
 {
     return(Request <TRequest, TResponse>(messageBus, requestPayload).GetResponseOrWait());
 }
示例#14
0
 /// <summary>
 /// Make a request of the given type on the default channel
 /// </summary>
 /// <typeparam name="TRequest">The type of request object</typeparam>
 /// <typeparam name="TResponse">The type of response object</typeparam>
 /// <param name="messageBus">The message bus</param>
 /// <param name="requestPayload">The request object, which represents the input arguments to the RPC</param>
 /// <returns>A token representing the subscription which, when disposed, cancels the subscription</returns>
 public static IRequest <TResponse> Request <TRequest, TResponse>(this IReqResBus messageBus, TRequest requestPayload)
 {
     Assert.ArgumentNotNull(messageBus, nameof(messageBus));
     return(messageBus.Request <TRequest, TResponse>(string.Empty, requestPayload));
 }
示例#15
0
 public static IDisposable ListenEnvelopeUntyped(this IReqResBus messageBus, Type requestType, Type responseType, string topic, object target, MethodInfo listener, bool useWeakReferences = false)
 {
     return(new UntypedListenerBuilder(messageBus).ListenEnvelopeUntyped(requestType, responseType, topic, target, listener, useWeakReferences));
 }
 public UntypedListenerBuilder(IReqResBus messageBus)
 {
     _messageBus = messageBus;
 }
示例#17
0
 public static WrappedFunction <TRequest, TResponse> WrapFunction <TRequest, TResponse>(this IReqResBus messageBus, Func <TRequest, TResponse> func, Action <IThreadListenerBuilder <TRequest, TResponse> > build)
 {
     return(new RequestFuncWrapper <TRequest, TResponse>().WrapFunction(messageBus, func, build));
 }
示例#18
0
 /// <summary>
 /// Get a typed request channel to simplify request/response calls
 /// </summary>
 /// <typeparam name="TRequest"></typeparam>
 /// <typeparam name="TResponse"></typeparam>
 /// <param name="messageBus"></param>
 /// <returns></returns>
 public static RequestChannelProxy <TRequest, TResponse> GetRequestChannel <TRequest, TResponse>(this IReqResBus messageBus)
 {
     return(new RequestChannelProxy <TRequest, TResponse>(messageBus));
 }
        public RequestChannelProxy(IReqResBus messageBus)
        {
            Assert.ArgumentNotNull(messageBus, nameof(messageBus));

            _messageBus = messageBus;
        }
示例#20
0
        public static IDisposable AutoWireupListeners(this IReqResBus messageBus, object obj, bool useWeakReferences = false)
        {
            var tokens = new ListenerScanner(messageBus, messageBus.Logger).DetectAndWireUpAll(obj, useWeakReferences);

            return(new DisposableCollection(tokens));
        }
示例#21
0
 public static IDisposable ListenUntyped(this IReqResBus messageBus, Type requestType, Type responseType, string topic, Func <object, object> handle, bool useWeakReferences = false)
 {
     return(new UntypedListenerBuilder(messageBus).ListenUntyped(requestType, responseType, topic, handle, useWeakReferences));
 }