Регистрация  |  Вход

Пишем красиво: делаем три колаута подряд

Всем привет!

Код - клиент SOAP web servica - делает колаут. Колаут взят в Трай-Кетч и если произошла ошибка при колауте, то код уходит в кетч.

Мне говорят: а если код уйдет в Кетч по причине тайм-аута у твоего колаута (не вернулся во время ответ по причине проблем со связью между серверами), ты не будешь пытаться еще раз сделать колаут?

Ок, давайте 3 раза подряд пытаться сделать колаут (без выяснения причин почему колаут не прошел).

получился такой код, посмотрите можно ли его как-то улучшить, или может делать какие паузы между вызовами.

спасибо

boolean ok;
System.CalloutException exception;

for (int i =1; i>3; i++){

try {

if (test.isRunningTest()) { output = testOutput; } // эта линия только на случай теста

else { output = stub.NewItem(xx, xxx); } // это колаут, который может вызвать ошибку по тайм-ауту

ok = true;

break; // прерываем цикл как только сделали колаут и не упали на нем

} catch (System.CalloutException e) {

exception = e;

ok = false;

}
} // закрываем цикл

if(!ok){

оправляем письмо счастья используя сообщение из exception;

return; // прерываем выполненние кода

}

и если дошли до этой линии, то уже работаем с результатом в output

Всем привет!

Код - клиент SOAP web servica - делает колаут. Колаут взят в Трай-Кетч  и если произошла ошибка при колауте, то код уходит в кетч.

Мне говорят: а если код уйдет в Кетч по причине тайм-аута у твоего колаута (не вернулся во время ответ по причине проблем со связью между серверами), ты не будешь пытаться еще раз сделать колаут?

Ок, давайте 3 раза подряд пытаться сделать колаут (без выяснения причин почему колаут не прошел).

получился такой код, посмотрите можно ли его как-то улучшить, или может делать какие паузы между вызовами.

спасибо

[code]
boolean ok;
System.CalloutException exception;

for (int i =1; i>3; i++){

 try {

    if (test.isRunningTest()) { output = testOutput; }  // эта линия только на случай теста

      else {  output = stub.NewItem(xx, xxx); }   // это колаут, который может вызвать ошибку по тайм-ауту
 
           ok = true;

           break; // прерываем цикл как только сделали колаут и не упали на нем

      } catch (System.CalloutException e) {

            exception = e;

            ok = false;

                          }
           } // закрываем цикл
  

 if(!ok){

            оправляем письмо счастья используя сообщение из exception;

             return;    // прерываем выполненние кода

              }

и если дошли до этой линии, то уже работаем с результатом в output

[/code]

Привет!

Как мне кажется, использовать еще ко всему и boolean ok; не очень обоснованно.
Во-первых, проверяй может лучше LoginResult или свой коннекшен по возвращаемому коду (200 и прочие), который тебе запрос вернет. ИМХО
Во-вторых. Что за мистическая цифра 3? Если тебе нужно сделать коллаут несмотря на дождь и слякоть отпрыгивай от лимитов

http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_methods_system_limits.htm

Integer countCallouts = Limits.getCallouts();
while ( countCallouts > 0){ ...
}

В-третьих. Ты обрабатываешь исключения? catch (System.CalloutException e) { exception = e; } - это обработка? А что дальше? Если это условно - то ок...а если это целостный кусок кода...то на исключение нужно как-то среагировать....

В-четвертых. try-catch-finally блок можно использовать

Привет!

Как мне кажется, использовать еще ко всему и boolean ok; не очень обоснованно. 
Во-первых, проверяй может лучше LoginResult или свой коннекшен по возвращаемому коду (200 и прочие), который тебе запрос вернет. ИМХО
Во-вторых. Что за мистическая цифра 3? Если тебе нужно сделать коллаут несмотря на дождь и слякоть отпрыгивай от лимитов

[url]http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_methods_system_limits.htm[/url]

[code]
Integer countCallouts = Limits.getCallouts();
while (  countCallouts  > 0){ ...
}

[/code]

В-третьих. Ты обрабатываешь исключения?   catch (System.CalloutException e) { exception = e; } - это обработка? А что дальше? Если это условно - то ок...а если это целостный кусок кода...то на исключение нужно как-то среагировать....

В-четвертых. try-catch-finally блок можно использовать

Art Vegas
Если тебе нужно сделать коллаут несмотря на дождь и слякоть отпрыгивай от лимитов

Integer countCallouts = Limits.getCallouts();
while ( countCallouts > 0){ ...
}

Вот это отличная идея. Спасибо

сейчас попробую сделать вот так:

while (  Limits.getLimitCallouts()  > 0){ 
...колаут...
}

по поводу обработки исключения - позже отпишусь в этом сообщении

PS: Limits.getLimitCallouts() > 0 - так не получается, оказывается это неизменная величина, я думал она менятся и показывает остаток возможных колаутов по ходу выполнения кода.

тогда попробую вот так:

boolean ok;
System.CalloutException myException;

while ( Limits.getCallouts() < Limits.getLimitCallouts() ){

try {

if (test.isRunningTest()) { output = testOutput; } // эта линия только на случай теста

else { output = stub.NewItem(xx, xxx); } // это колаут, который может вызвать ошибку по тайм-ауту

ok = true;

break; // прерываем цикл как только сделали колаут и не упали на нем

} catch (System.CalloutException e) {

myException = e;

ok = false;

}
} // закрываем цикл

if(!ok){

// обработка исключения c использованием myException

return; // прерываем выполненние кода

}

//и если дошли до этой линии, то уже работаем с результатом в output

PSS: да, вариант выше делает десять неуспешных вызовов подряд (или обрывает цикл после первого успешного).
Обработку исключения я перенес вне цикла, в секцию if(!ok), так мне не нужно обрабатывать каждую неудачную попытку, а только если все 10 неудачны.

Проблемы:
(1) не могу спровоцировать ошибку по тайм-ауту. Ставлю неверный end point (УРЛ) в вызове, но тогда получается ошибка:
Exeption message: System.CalloutException: Web service callout failed: Unexpected element... but found ':HTML'.
судя по всему провайдер ставит какую страницу-заглушку в случае несуществующего УРЛ;

(2) не получилось дебажить колаут в Эклипсе.
в Эклипсе в Execute Anonymous можно спровоцировать тригер, который который сделает ауткол с помощью футут метода, но дебажные данные асинхронного процесса не попадают в дебаг лог.
можно убрать футур аннотацию из класса и вызвать его метод прямо, но без футур аннотации не происходит сам колаут, он возвращает ошибку. В-общем, дебажу в Орге...

[quote="Art Vegas"] Если тебе нужно сделать коллаут несмотря на дождь и слякоть отпрыгивай от лимитов

[code]
Integer countCallouts = Limits.getCallouts();
while (  countCallouts  > 0){ ...
}

[/code]

[/quote]

Вот это отличная идея. Спасибо

сейчас попробую сделать вот так:

[code]while (  Limits.getLimitCallouts()  > 0){ 
...колаут...
}[/code]

по поводу обработки исключения -  позже отпишусь в этом сообщении

[b]PS: [/b] Limits.getLimitCallouts()  > 0 - так не получается, оказывается это неизменная величина, я думал она менятся и показывает остаток возможных колаутов по ходу выполнения кода.

тогда попробую вот так:

[code]

boolean ok;
System.CalloutException myException;

while (  Limits.getCallouts()  <  Limits.getLimitCallouts()  ){ 

 try {

    if (test.isRunningTest()) { output = testOutput; }  // эта линия только на случай теста

      else {  output = stub.NewItem(xx, xxx); }   // это колаут, который может вызвать ошибку по тайм-ауту
 
           ok = true;

           break;  // прерываем цикл как только сделали колаут и не упали на нем

      } catch (System.CalloutException e) {

            myException = e;

            ok = false;

                          }
           } // закрываем цикл
 

 if(!ok){

            // обработка исключения c использованием myException

             return;    // прерываем выполненние кода

              }

            //и если дошли до этой линии, то уже работаем с результатом в output

[/code]

[b]PSS: [/b]да, вариант выше делает десять неуспешных вызовов подряд (или обрывает цикл после первого успешного).
Обработку исключения я перенес вне цикла, в секцию if(!ok), так мне не нужно обрабатывать каждую неудачную попытку, а только если все 10 неудачны.

Проблемы:
(1) не могу спровоцировать ошибку по тайм-ауту. Ставлю неверный end point (УРЛ) в вызове, но тогда получается ошибка:
[i]Exeption message: System.CalloutException: Web service callout failed: Unexpected element... but found ':HTML'.[/i]
судя по всему провайдер ставит какую страницу-заглушку в случае несуществующего УРЛ;

(2) не получилось дебажить колаут в Эклипсе.
в Эклипсе в Execute Anonymous можно спровоцировать тригер, который который сделает ауткол с помощью футут метода, но дебажные данные асинхронного процесса не попадают в дебаг лог.
можно убрать футур аннотацию из класса и вызвать его метод прямо, но без футур аннотации не происходит сам колаут, он возвращает ошибку. В-общем, дебажу в Орге...