Страница 1 из 1

TMSServiceBroker перестал работать в составе службы Windows

Добавлено: Пн 19 окт 2015 09:33
saupg
Здравствуйте!

Пытаюсь перейти на SDAC версии 7.2.8 с версии 6.11.23. Использую Delphi XE6.

Существует служба Windows (TService), которая с помощью компоненты TMSServiceBroker отслеживает сообщения в очереди брокера, отправляемые туда по расписанию заданиями SQL-сервера.

При компиляции этой службы на SDAC v7 сообщения из очереди забираются, но их обработка не выполняется (событие MSServiceBrokerBeginConversation не вызывается).

Поизучал ваши исходники и выяснил, что перестал работать таймер, по которому обрабатывались полученные сообщения из очереди. TMSServiceBroker использует отдельный поток для обработки полученных сообщений - класс TCRThreadWrapper.

1. В методе TCRThreadWrapper.SetTimer таймер теперь активируется только при условии выполнения в главном потоке (используется функция IsMainThread)! В случае службы Windows таймер не запускается никогда:

Код: Выделить всё

procedure TCRThreadWrapper.SetTimer;
const
  USER_TIMER_MINIMUM = $A;
begin
  if FTimer = nil then begin
    FTimer := TCRTimer.Create(nil);
    FTimer.Enabled := False;
    FTimer.Interval := USER_TIMER_MINIMUM;
    FTimer.OnTimer := DoTimer;
  end;

  Assert(not FTimer.Enabled);
  if IsMainThread then
    FTimer.Enabled := True;
end;
2. Собственно, метод SetTimer также не вызывается. В конструкторе используется та же проверка IsMainThread:

Код: Выделить всё

constructor TCRThreadWrapper.Create;
begin
  inherited Create;

  FLockState := {$IFDEF FPC}SyncObjs.{$ENDIF}TCriticalSection.Create;
  FThreadState := tsSuspended;
  FEvents := TThreadList.Create;
  FSendEventProcessed := TEvent.Create(nil, True, False, '');
  FThread := TCRThread.Create(Self);

  if IsMainThread then
    SetTimer
  else
    NeedToSetTimerList.Add(Self);
end;
Но список NeedToSetTimerList обрабатывается только в методе DoTimer, который вызывается по таймеру, создаваемому в методе SetTimer. Вот так круг замкнулся.

Помогите, пожалуйста. Как теперь использовать ваш компонент в службе Windows?

Re: TMSServiceBroker перестал работать в составе службы Windows

Добавлено: Ср 21 окт 2015 09:08
AndreyZ
Спасибо за информацию. Мы воспроизвели описанное вами поведение и будем его исследовать. Мы сообщим вам о полученных результатах.

Re: TMSServiceBroker перестал работать в составе службы Windows

Добавлено: Ср 02 мар 2016 17:10
saupg
Обновился до версии SDAC 7.2.10 в ожидании исправления обсуждаемой ситуации (в описании версии 7.2.9 увидел "Bug with using TMSServiceBroker in Windows service is fixed").

По факту - снова не работает. Подскажите, что нужно сделать, чтобы сообщения начали обрабатываться.

Есть подозрение, что метод StartAsyncEventProcessor в модуле CRThread.pas как-то с этим связан, не даром вы к нему добавили параметр "Force: Boolean". Только вот метод этот нигде не используется. В документации найти упоминания о нём не удалось. Мне нужно его вызывать при запуске windows-службы или что?

Re: TMSServiceBroker перестал работать в составе службы Windows

Добавлено: Чт 03 мар 2016 12:38
Alexp
Вам необходимо явно в вашем приложении вызывать метод StartAsyncEventProcessor, для работы в службе.

Re: TMSServiceBroker перестал работать в составе службы Windows

Добавлено: Чт 03 мар 2016 13:07
saupg
Подскажите пожалуйста, в каком событии (в какой момент) необходимо вызывать этот метод?

Re: TMSServiceBroker перестал работать в составе службы Windows

Добавлено: Ср 09 мар 2016 12:49
AndreyZ
Добавьте вызов процедуры StartAsyncEventProcessor в initialization секцию вашей службы. Например:

Код: Выделить всё

unit CoolService;

interface
...
type
  TCoolService = class(TService)
...
  end;
...
initialization
  StartAsyncEventProcessor(True);
end.

Re: TMSServiceBroker перестал работать в составе службы Windows

Добавлено: Вт 29 мар 2016 14:14
saupg
Теперь наблюдаются проблемы со стабильностью.
1. Какое-то время служба работает нормально и обрабатывает сообщения, потом перестаёт (при этом сообщения из очереди брокера пропадают).
2. После запуска службы сообщения не обрабатываются (при этом сообщения из очереди брокера пропадают), но при помощи перезапуска службы сообщения вдруг начинают приниматься, но вскоре всё равно всё упирается в п.1.
Нет ли каких-либо идей на этот счёт?

Re: TMSServiceBroker перестал работать в составе службы Windows

Добавлено: Пт 01 апр 2016 13:09
AndreyZ
Постарайтесь составить небольшой пример, на котором можно будет воспроизвести эту проблему, и пришлите его на andreyz*devart*com.