Beispiel #1
0
 public RemoteScannerInterface(
     ILogger logger,
     CallPropertiesConfig commonCallProperties,
     CallPropertiesConfig synchronizationCallProperties,
     CallPropertiesConfig printingCallProperties)
 {
     CodeContract.Requires(logger != null);
     CodeContract.Requires(commonCallProperties != null);
     CodeContract.Requires(synchronizationCallProperties != null);
     CodeContract.Requires(printingCallProperties != null);
     _logger = logger;
     _commonCallProperties          = commonCallProperties;
     _synchronizationCallProperties = synchronizationCallProperties;
     _printingCallProperties        = printingCallProperties;
 }
Beispiel #2
0
        private T SafeCall <T>(Func <T> method, CallPropertiesConfig callProps, T returnOnError)
        {
            if (!_alive)
            {
                return(returnOnError);
            }
            var tryCount       = 0;
            var methodComplete = new AutoResetEvent(false);

            while (!_disposed && _alive)
            {
                try
                {
                    var       result   = default(T);
                    Exception methodEx = null;
                    methodComplete.Reset();
                    var thread = ThreadUtils.StartBackgroundThread(
                        () =>
                    {
                        try
                        {
                            result = method();
                        }
                        catch (Exception ex)
                        {
                            methodEx = ex;
                        }
                        finally
                        {
                            methodComplete.Set();
                        }
                    });
                    if (!methodComplete.WaitOne(callProps.Timeout))
                    {
                        thread.SafeAbort();
                        throw new TimeoutException("Не дождались завершение выполнения метода");
                    }
                    if (methodEx != null)
                    {
                        throw methodEx;
                    }
                    return(result);
                }
                catch (Exception ex)
                {
                    _logger.LogVerbose(
                        Message.SyncCallRemoteMethodFailed,
                        () =>
                    {
                        var methodInfo = (new StackTrace()).GetFrame(3).GetMethod();
                        return(new object[] { methodInfo.Name, ex.ToString() });
                    });
                    if ( // ошибка не из-за сети
                        ((!(ex is SocketException) && !(ex is RemotingException)) && !(ex is TimeoutException)) ||
                        ++tryCount >= callProps.MaxTryCount ||
                        !_alive ||
                        _disposed)
                    {
                        RaiseDisconnected();
                        return(returnOnError);
                    }
                    if (!Monitor.TryEnter(s_ifrestartSync))
                    {
                        Thread.Sleep(300);
                        _ifrestartDoneEvent.WaitOne(TimeSpan.FromMinutes(1));
                        continue;
                    }
                    try
                    {
                        _ifrestartDoneEvent.Reset();
                        IfrestartResult res;
                        if (PlatformDetector.IsUnix)
                        {
                            _logger.LogVerbose(Message.SyncIfrestartStarting);
                            string lastLine = null;
                            ProcessHelper.StartProcessAndWaitForFinished(
                                "./ifrestart.sh",
                                string.Format("{0} {1}", callProps.RetryDelay, _remoteScannerInfo.IpAddress),
                                state =>
                            {
                                lastLine = state.Line;
                                return(false);
                            },
                                null);
                            _logger.LogVerbose(Message.SyncIfrestartDone, lastLine);
                            int i;
                            res = int.TryParse(lastLine, out i)
                                      ? (IfrestartResult)i
                                      : IfrestartResult.Failed;
                        }
                        else
                        {
                            _logger.LogVerbose(Message.Common_Debug,
                                               "Имитируем выполнение команды переподнятия сети");
                            Thread.Sleep(4000 + callProps.RetryDelay * 2 * 1000);
                            res = IfrestartResult.OkAfterRestart;
                        }
                        switch (res)
                        {
                        case IfrestartResult.OkAfterRestart:
                            _logger.LogVerbose(Message.SyncTryCallRemoteMethodAgain,
                                               () =>
                            {
                                var methodInfo = (new StackTrace()).GetFrame(3).GetMethod();
                                return(new object[] { methodInfo.Name, tryCount + 1 });
                            });
                            continue;

                        default:
                            RaiseDisconnected();
                            return(returnOnError);
                        }
                    }
                    finally
                    {
                        Monitor.Exit(s_ifrestartSync);
                        _ifrestartDoneEvent.Set();
                    }
                }
            }
            return(returnOnError);
        }