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




Следите за тем, когда вы в последний раз успешно заходили на сервер. Если сервер выдает исключение, перехватите его и сравните с тем, когда вы в последний раз заходили на сервер. Если это время больше минуты, повторно вызовите исключение.
Вам нужно будет записать время, когда вы изначально пытались подключиться к серверу, а затем перехватить исключение. если время, в течение которого было обнаружено исключение, больше, чем исходное время + 1 минута, повторно вызовите исключение. Если нет, попробуйте еще раз.
В идеале вы можете поставить таймаут на вызов сервера. В противном случае выполните thread.sleep (600) в блоке catch и попробуйте еще раз и завершитесь неудачно, если второй не вернется.
В псевдокоде.
//Create Timer
//Start Timer
bool connected = false;
while (!connected)
try {
//Connect To DB
connected = true;
}
catch (Exception ex) {
if (more than 1 minute has passed)
throw new Exception(ex);
}
}
У вас может быть счетчик повторных попыток, и если желаемое количество (6 в вашем случае) было выполнено, выбросить исключение
int count = 0;
CheckServer(count);
public void CheckServer(count) {
try
{
// connect to server
}
catch(Exception e)
{
if (count < MAX_ATTEMPTS) {
// wait 10 seconds
CheckServer(count++)
}
else {
throw e;
}
}
}
Вы можете установить логическую переменную, показывающую, успешно ли выполнено соединение с сервером, и проверить ее в обработчике исключений, например:
class ServerTester : public Object
{
private bool failing;
private ServerConnection serverConnection;
private Time firstFailure;
public ServerTester(): failing(false)
{
}
public void TestServer() throws ServerException
{
try
{
serverConnection.Connect();
failing = false;
}
catch (ServerException e)
{
if (failing)
{
if (Time::GetTime() - firstFailure > 60)
{
failing = false;
throw e;
}
}
else
{
firstFailure = Time::GetTime();
failing = true;
}
}
}
}
Я не знаю, каковы реальные API времени, так как я в последний раз использовал Java довольно давно. Это сделает то, о чем вы просите, но что-то в этом не кажется правильным. Опрос на исключения кажется мне немного отсталым, но, поскольку вы имеете дело с сервером, я не могу придумать другого выхода из головы.
Помните, что обработка исключений - это просто очень специализированное использование обычной системы «возврата». (Дополнительные технические подробности см. В «монадах».) Если исключительная ситуация, о которой вы хотите сообщить, не подходит естественным образом в систему обработки исключений Java, она может не подходить для исключений использовать.
Вы можете отслеживать условия ошибки обычным способом: сохранять переменную состояния, обновлять ее по мере необходимости, добавляя информацию об успехе / неудаче, и соответствующим образом реагировать при изменении состояния.
Сервер на самом деле не генерирует исключение, это вызывает код клиента;) Тем не менее, я все же проголосовал за ваш ответ +1.