#include "path-util.h"
#include "ipwd.h"
#include "str.h"
+#include "time-util.h"
#include "execv-const.h"
#include "restrict-process-size.h"
#include "master-instance.h"
secs = old_time->tv_sec - new_time->tv_sec + 1;
if (secs > SERVICE_TIME_MOVED_BACKWARDS_MAX_THROTTLE_SECS)
secs = SERVICE_TIME_MOVED_BACKWARDS_MAX_THROTTLE_SECS;
- services_throttle_time_sensitives(services, secs);
+ services_throttle_time_sensitives(services, secs * 1000);
i_warning("Time moved backwards by %"PRIdTIME_T" seconds, waiting for "
"%"PRIdTIME_T" secs until new services are launched again.",
old_time - new_time, secs);
str_printfa(str, "\t%u\t%u\t%u\t%u\t%u\t%ld\t%u\t%ld\t%c\t%c\t%c\t%"PRIu64"\n",
service->process_count, service->process_avail,
service->process_limit, service->client_limit,
- service->to_throttle == NULL ? 0 : service->throttle_secs,
+ (service->to_throttle == NULL ?
+ 0 : ((service->throttle_msecs + 999) / 1000)),
(long)service->exit_failure_last,
service->exit_failures_in_sec,
(long)service->last_drop_warning,
if (service->to_throttle != NULL || service->list->destroying)
return;
- i_assert(service->throttle_secs > 0);
-
- service_error(service, "command startup failed, throttling for %u secs",
- service->throttle_secs);
- service_throttle(service, service->throttle_secs);
- service->throttle_secs *= 2;
- if (service->throttle_secs > SERVICE_STARTUP_FAILURE_THROTTLE_MAX_SECS)
- service->throttle_secs = SERVICE_STARTUP_FAILURE_THROTTLE_MAX_SECS;
+ i_assert(service->throttle_msecs > 0);
+
+ service_error(service,
+ "command startup failed, throttling for %u.%03u secs",
+ service->throttle_msecs / 1000,
+ service->throttle_msecs % 1000);
+ service_throttle(service, service->throttle_msecs);
+ service->throttle_msecs *= 2;
+ if (service->throttle_msecs >
+ SERVICE_STARTUP_FAILURE_THROTTLE_MAX_MSECS) {
+ service->throttle_msecs =
+ SERVICE_STARTUP_FAILURE_THROTTLE_MAX_MSECS;
+ }
}
static void service_drop_timeout(struct service *service)
/* success - one success resets all failures */
service->have_successful_exits = TRUE;
service->exit_failures_in_sec = 0;
- service->throttle_secs =
- SERVICE_STARTUP_FAILURE_THROTTLE_MIN_SECS;
+ service->throttle_msecs =
+ SERVICE_STARTUP_FAILURE_THROTTLE_MIN_MSECS;
throttle = FALSE;
} else {
throttle = service_process_failure(process, status);
service = p_new(pool, struct service, 1);
service->list = service_list;
service->set = set;
- service->throttle_secs = SERVICE_STARTUP_FAILURE_THROTTLE_MIN_SECS;
+ service->throttle_msecs = SERVICE_STARTUP_FAILURE_THROTTLE_MIN_MSECS;
service->client_limit = set->client_limit != 0 ? set->client_limit :
set->master_set->default_client_limit;
}
}
-void service_throttle(struct service *service, unsigned int secs)
+void service_throttle(struct service *service, unsigned int msecs)
{
if (service->to_throttle != NULL || service->list->destroyed)
return;
service_drop_listener_connections(service);
service_monitor_listen_stop(service);
- service->to_throttle = timeout_add(secs * 1000,
- service_throttle_timeout, service);
+ service->to_throttle = timeout_add(msecs, service_throttle_timeout,
+ service);
}
void services_throttle_time_sensitives(struct service_list *list,
- unsigned int secs)
+ unsigned int msecs)
{
struct service *const *services;
struct service *service = *services;
if (service->type == SERVICE_TYPE_UNKNOWN)
- service_throttle(service, secs);
+ service_throttle(service, msecs);
}
}
this many seconds, kill the process */
#define SERVICE_FIRST_STATUS_TIMEOUT_SECS 30
-#define SERVICE_STARTUP_FAILURE_THROTTLE_MIN_SECS 2
-#define SERVICE_STARTUP_FAILURE_THROTTLE_MAX_SECS 60
+#define SERVICE_STARTUP_FAILURE_THROTTLE_MIN_MSECS (2*1000)
+#define SERVICE_STARTUP_FAILURE_THROTTLE_MAX_MSECS (60*1000)
enum service_listener_type {
SERVICE_LISTENER_UNIX,
int master_dead_pipe_fd[2];
- unsigned int throttle_secs;
+ unsigned int throttle_msecs;
time_t exit_failure_last;
unsigned int exit_failures_in_sec;
void service_login_notify(struct service *service, bool all_processes_full);
/* Prevent service from launching new processes for a while. */
-void service_throttle(struct service *service, unsigned int secs);
+void service_throttle(struct service *service, unsigned int msecs);
/* Time moved backwards. Throttle services that care about time. */
void services_throttle_time_sensitives(struct service_list *list,
- unsigned int secs);
+ unsigned int msecs);
/* Find service by name. */
struct service *