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

Обсуждение возникших проблем, предложений и ошибок SDAC компонентов
Ответить
saupg
Сообщения: 18
Зарегистрирован: Вт 06 май 2014 07:01

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

Сообщение saupg » Пн 19 окт 2015 09:33

Здравствуйте!

Пытаюсь перейти на 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?

AndreyZ
Devart Team
Сообщения: 328
Зарегистрирован: Чт 08 сен 2011 13:18

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

Сообщение AndreyZ » Ср 21 окт 2015 09:08

Спасибо за информацию. Мы воспроизвели описанное вами поведение и будем его исследовать. Мы сообщим вам о полученных результатах.

saupg
Сообщения: 18
Зарегистрирован: Вт 06 май 2014 07:01

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

Сообщение saupg » Ср 02 мар 2016 17:10

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

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

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

Alexp
Devart Team
Сообщения: 349
Зарегистрирован: Пн 27 дек 2010 10:34

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

Сообщение Alexp » Чт 03 мар 2016 12:38

Вам необходимо явно в вашем приложении вызывать метод StartAsyncEventProcessor, для работы в службе.

saupg
Сообщения: 18
Зарегистрирован: Вт 06 май 2014 07:01

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

Сообщение saupg » Чт 03 мар 2016 13:07

Подскажите пожалуйста, в каком событии (в какой момент) необходимо вызывать этот метод?

AndreyZ
Devart Team
Сообщения: 328
Зарегистрирован: Чт 08 сен 2011 13:18

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

Сообщение AndreyZ » Ср 09 мар 2016 12:49

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

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

unit CoolService;

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

saupg
Сообщения: 18
Зарегистрирован: Вт 06 май 2014 07:01

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

Сообщение saupg » Вт 29 мар 2016 14:14

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

AndreyZ
Devart Team
Сообщения: 328
Зарегистрирован: Чт 08 сен 2011 13:18

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

Сообщение AndreyZ » Пт 01 апр 2016 13:09

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

Ответить