Вызов WebRequest в OnDeinit

 

При снятии советника с графика должен отправляться запрос с сообщением об остановке и я поместил его в OnDeinit с расчетом что он вызовется и запрос отправится

void OnDeinit(const int reason)
  {
   restClient.UpdateInstanceStatus("STOPPED");
   delete restClient;
  }

Внутри объекта restClient:

   int               UpdateInstanceStatus(string status)
     {
      char serverResult[];
      string serverHeaders;
      uchar jsonData[];
      string body = "{\"status\":\"" + status + "\"}";
      StringToCharArray(body, jsonData, 0, StringLen(body));
      string endpoint = URL + "/api/trade/instances/" + _magic + "/status/update";
      return WebRequest("POST", endpoint, GetHeaders(), 10000, jsonData, serverResult, serverHeaders);
     }

Но по какой-то причине именно при вызове в OnDeinit метод UpdateInstanceStatus всегда возвращает 1001, а до сервера запрос вообще не долетает.

При вызове в других местах такой проблемы нет, и обновление статуса работает нормально.

Это означает что в  OnDeinit  функцию WebRequest вызывать уже нельзя не смотря на то что объект restClient в полном порядке? Или тут есть нюансы как можно все таки послать запрос?

Цель всей конструкции это сменить статус инстанса советника на сервере каким бы способом не был остановлен советник. Может есть другой метод жизненного цикла который позволяет вызвать WebRequest?  

 
Павел Раввич:

При снятии советника с графика должен отправляться запрос с сообщением об остановке и я поместил его в OnDeinit с расчетом что он вызовется и запрос отправится

Внутри объекта restClient:

Но по какой-то причине именно при вызове в OnDeinit метод UpdateInstanceStatus всегда возвращает 1001, а до сервера запрос вообще не долетает.

При вызове в других местах такой проблемы нет, и обновление статуса работает нормально.

Это означает что в  OnDeinit  функцию WebRequest вызывать уже нельзя не смотря на то что объект restClient в полном порядке? Или тут есть нюансы как можно все таки послать запрос?

Цель всей конструкции это сменить статус инстанса советника на сервере каким бы способом не был остановлен советник. Может есть другой метод жизненного цикла который позволяет вызвать WebRequest?  

Наверное несмотря на незавершённую работу удаляется объект restClient

Попробуйте вынести restClient.UpdateInstanceStatus("STOPPED"); в пользовательскую функцию типа bool и только после возврата из неё объект restClient будет удалён.

Что-то типа так

void OnDeinit(const int reason)
  {
   dool res = myDeinit();
   delete restClient;
  }

bool myDeinit()
{
 restClient.UpdateInstanceStatus("STOPPED");
 return true;
}
 
Павел Раввич:

При снятии советника с графика должен отправляться запрос с сообщением об остановке и я поместил его в OnDeinit с расчетом что он вызовется и запрос отправится

Внутри объекта restClient:

Но по какой-то причине именно при вызове в OnDeinit метод UpdateInstanceStatus всегда возвращает 1001, а до сервера запрос вообще не долетает.

При вызове в других местах такой проблемы нет, и обновление статуса работает нормально.

Это означает что в  OnDeinit  функцию WebRequest вызывать уже нельзя не смотря на то что объект restClient в полном порядке? Или тут есть нюансы как можно все таки послать запрос?

Цель всей конструкции это сменить статус инстанса советника на сервере каким бы способом не был остановлен советник. Может есть другой метод жизненного цикла который позволяет вызвать WebRequest?  

то что WebRequest перестаёт работать в OnDeinit (возможно даже сразу после ExpertRemove или флага IsStopped) ничего удивительного нет. Таймеры останавливаются, хендлы удаляются, ресурсы освобождаются.

если сервер ваш, то можно выкрутиться сделав HeartBeat - клиент при простоях (или периодически) шлёт HB, говоря что "жив курилка". Если сервер не получает HB то тыдыщь.

 
заведите канарейку
 
Павел Раввич:

кстати, если не принципиально "не использовать DLL",

то обмен данными с сервером лучше выносить именно туда. И даже в отдельный поток.

Тогда всё можно, а советник делает своё дело (считает и торгует), и не занимается всякой фигнёй типа сетевой запрос/ответ, парса и формирования json

 
Alexey Viktorov:

Наверное несмотря на незавершённую работу удаляется объект restClient

Попробуйте вынести restClient.UpdateInstanceStatus("STOPPED"); в пользовательскую функцию типа bool и только после возврата из неё объект restClient будет удалён.

Что-то типа так

Я смотрел в дебаге что объект restClient в порядке да и его удаление я пробовал вообще убрать, проблема точно не в том что он уже удален к тому же в mql наверняка есть свой happen beffore.   

 
Maxim Kuznetsov:

кстати, если не принципиально "не использовать DLL",

то обмен данными с сервером лучше выносить именно туда. И даже в отдельный поток.

Тогда всё можно, а советник делает своё дело (считает и торгует), и не занимается всякой фигнёй типа сетевой запрос/ответ, парса и формирования json

DLL это я на долго завязну тут либо C# или плюсы а у меня стек java\js хардбит то что нужно.

 
Павел Раввич:

Я смотрел в дебаге что объект restClient в порядке да и его удаление я пробовал вообще убрать, проблема точно не в том что он уже удален к тому же в mql наверняка есть свой happen beffore.   

Прочтите это сообщение Рашида. И обратите внимание на первый его вопрос: «Что происходит при удалении указателя?»

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Ошибки, баги, вопросы

Rashid Umarov, 2020.07.11 16:39

А что происходит при удалении указателя?

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
  
  CChartObjectTrend * trend;
  
  int i = listOfTrendLines.Total() - 1;
  for(; i >= 0; i--) {
    trend = dynamic_cast <CChartObjectTrend *> (listOfTrendLines.At(i));
    
    if(CheckPointer(trend) == POINTER_INVALID)
      continue;
    
    delete trend;
  }
}

Идет команда графику на удаление графического объекта? Смотрите примечание к ObjectDelete

И обратите внимание, что это вопрос гораздо проще чем ваш. Всего-лишь удаление графических объектов…

Ну, если я не прав……… извиняйте.

 
Павел Раввич:

DLL это я на долго завязну тут либо C# или плюсы а у меня стек java\js хардбит то что нужно.

js стек сложно втащить в MT. То есть для сам по себе ECMA есть удобно встраиваемые кандидаты, а со всей привычной людям инфраструктурой пожалуй что нет.

а вот с java можно было-бы заморочиться раз, и получить MT+embed_java<->сеть<->java_server.

меня когда-то остановило что не на том уровне знаю java - встроить её понятно как, а отладить и эффективно использовать увы и ах :-)

 
Maxim Kuznetsov:

js стек сложно втащить в MT. То есть для сам по себе ECMA есть удобно встраиваемые кандидаты, а со всей привычной людям инфраструктурой пожалуй что нет.

а вот с java можно было-бы заморочиться раз, и получить MT+embed_java<->сеть<->java_server.

меня когда-то остановило что не на том уровне знаю java - встроить её понятно как, а отладить и эффективно использовать увы и ах :-)

Эх может эта тема для проекта... у меня в точности наоборот java основной инструмент и сервак на ней. Но как встроить ее ума не приложу только и остается что запросы WebRequest посылать. А как хотя бы примерно в двух словах вы планировали  MT+embed_java делать?

 
Павел Раввич:

Эх может эта тема для проекта... у меня в точности наоборот java основной инструмент и сервак на ней. Но как встроить ее ума не приложу только и остается что запросы WebRequest посылать. А как хотя бы примерно в двух словах вы планировали  MT+embed_java делать?

у java машины есть хорошо прописанный,устойчивый и документированный C-интерфейс.

Один раз написать DLL про запуск и остановку машины (конкуренцию нескольких или пула) и обмен данными.
Не особо много кода на С/С++ и получится кстати. Есть над чем поломать голову, но это не мегабайты кода.
Де-факто выйдет (сокращённый)порт имеющего API на MQL, и пофантазировать про event-queue.

Потом про обмен данными по желанию сделать шаблоны/классы MQL, чтобы приклады были покороче.

Я встраивал Tcl/Tk (и до сих пор им пользуюсь), но перед этим рассматривал,крутил/вертел разные варианты и java тоже.
Для моих целей java это перебор :-)

Причина обращения: