public static ServiceReferences.RemoteExecutorServiceResult Convert(this Services.RemoteExecutorServiceResult result)
        {
            var res = new ServiceReferences.RemoteExecutorServiceResult()
            {
                Result = result.Result,
                ExecutorState = (ServiceReferences.ExecutorState)((int)result.ExecutorState),
                Error = result.Error,
                ElapsedTime = result.ElapsedTime
            };

            return res;
        }
Пример #2
0
        public void ExecutesOnRemoteThread()
        {
            Func<object[], object> function = (parameters) =>
            {
                var a = (int)parameters[0];
                var b = (int)parameters[1];

                return a + b;
            };

            var remoteExecutorId = Guid.Empty;
            var serviceMock = new Mock<Bluepath.ServiceReferences.IRemoteExecutorService>(MockBehavior.Strict);
            var result  = new ServiceReferences.RemoteExecutorServiceResult()
                        {
                            ExecutorState = ServiceReferences.ExecutorState.Finished,
                            Result = 6
                        };

            serviceMock.Setup(rs => rs.Initialize(It.IsAny<byte[]>()))
                .Returns(() =>
                {
                    remoteExecutorId = Guid.NewGuid();
                    return remoteExecutorId;
                });
            serviceMock.Setup(rs => rs.ExecuteAsync(It.IsAny<Guid>(), It.IsAny<object[]>(), It.IsAny<Bluepath.ServiceReferences.ServiceUri>()))
                .Returns(() => Task.Run(() => Services.RemoteExecutorService.GetRemoteExecutor(remoteExecutorId).Pulse(result)));
            serviceMock.Setup(rs => rs.TryJoin(It.IsAny<Guid>())).Returns(result);

            var schedulerMock = new Mock<IScheduler>(MockBehavior.Strict);
            schedulerMock.Setup(s => s.GetRemoteService()).Returns(serviceMock.Object);

            var dt1 = Bluepath.Threading.DistributedThread<Func<object[], object>>.Create(
                function,
                new ConnectionManager(remoteServices: null, listener: null),
                schedulerMock.Object,
                Threading.DistributedThread.ExecutorSelectionMode.RemoteOnly);
            dt1.Start(4, 2);
            dt1.Join();

            Convert.ToInt32(dt1.Result).ShouldBe(6);
        }
Пример #3
0
        /// <summary>
        /// Executes method set previously by Initialize method.
        /// </summary>
        /// <param name="eid">Unique identifier of the executor.</param>
        /// <param name="parameters">Parameters for the method. Note that it gets interpreted as object1, object2, etc.
        /// So if method expects one argument of type object[], you need to wrap it with additional object[] 
        /// (object[] { object[] } - outer array indicates that method accepts one parameter, and inner is actual parameter).</param>
        /// <param name="callbackUri">Specifies uri which will be used for callback.
        /// Null for no callback.</param>
        public void Execute(Guid eid, object[] parameters, ServiceUri callbackUri)
        {
            var executor = GetExecutor(eid);

            Log.TraceMessage(
                callbackUri != null ? Log.Activity.Starting_local_executor_with_callback : Log.Activity.Starting_local_executor_without_callback,
                string.Format(
                        "Starting local executor. Upon completion callback will{0} be sent{1}{2}.",
                        callbackUri != null ? string.Empty : " not",
                        callbackUri != null ? " to " : string.Empty,
                        callbackUri != null ? callbackUri.Address : string.Empty),
                        keywords: executor.Eid.EidAsLogKeywords());

            executor.Execute(parameters);

            if (callbackUri != null)
            {
                var t = new Thread(() =>
                {
                    try
                    {
                        using (var client =
                            new Bluepath.ServiceReferences.RemoteExecutorServiceClient(
                                callbackUri.Binding,
                                callbackUri.ToEndpointAddress()))
                        {
                            // Join on local executor doesn't throw exceptions by design
                            // Exception caused by user code (if any) can be accessed using Exception property
                            executor.Join();

                            Log.TraceMessage(Log.Activity.Sending_callback_with_result, string.Format("Sending callback with result. State: {0}. Elapsed time: {1}.", executor.ExecutorState, executor.ElapsedTime), keywords: executor.Eid.EidAsLogKeywords());

                            var result = new ServiceReferences.RemoteExecutorServiceResult
                            {
                                Result = executor.IsResultAvailable ? executor.Result : null,
                                ElapsedTime = executor.ElapsedTime,
                                ExecutorState = (ServiceReferences.ExecutorState)((int)executor.ExecutorState),
                                Error = executor.Exception
                            };

                            // TODO: Serialization of result can fail and we should do something about it (like send an error message back)
                            client.ExecuteCallback(eid, result);
                        }
                    }
                    catch(Exception ex)
                    {
                        Log.ExceptionMessage(ex, Log.Activity.Send_callback_failed, "Send callback failed.");
                    }
                });

                t.Name = string.Format("Execute callback sender thread for executor '{0}'", executor.Eid);
                t.Start();
            }
        }