* Rewrork the CWC reconnection strategy.

If there are active subscription, Tvheadend will attempt to reconnect
    immediately and then retry every three seconds.
    If no subscription is active a reconnection attempt is performed
    every minute.
    Also, if any CWC configuration changes are made from the UI, Tvheadend
    will try to reconnect directly.
This commit is contained in:
Andreas Öman 2009-07-26 10:11:43 +00:00
parent 1e5631c81d
commit 7cab70e1e5
4 changed files with 67 additions and 27 deletions

8
debian/changelog vendored
View file

@ -17,6 +17,14 @@ hts-tvheadend (2.4) hts; urgency=low
* Use absolute paths when serving static content (the web app itself) * Use absolute paths when serving static content (the web app itself)
This was only a problem when fork()ing a development build This was only a problem when fork()ing a development build
* Rewrork the CWC reconnection strategy.
If there are active subscription, Tvheadend will attempt to reconnect
immediately and then retry every three seconds.
If no subscription is active a reconnection attempt is performed
every minute.
Also, if any CWC configuration changes are made from the UI, Tvheadend
will try to reconnect directly.
hts-tvheadend (2.3) hts; urgency=low hts-tvheadend (2.3) hts; urgency=low
* A simple web interface has been added. To access it, visit * A simple web interface has been added. To access it, visit

View file

@ -79,6 +79,7 @@ typedef enum {
TAILQ_HEAD(cwc_queue, cwc); TAILQ_HEAD(cwc_queue, cwc);
LIST_HEAD(cwc_transport_list, cwc_transport); LIST_HEAD(cwc_transport_list, cwc_transport);
static struct cwc_queue cwcs; static struct cwc_queue cwcs;
static pthread_cond_t cwc_config_changed;
/** /**
@ -741,12 +742,13 @@ cwc_thread(void *aux)
{ {
cwc_transport_t *ct; cwc_transport_t *ct;
cwc_t *cwc = aux; cwc_t *cwc = aux;
int fd; int fd, d;
char errbuf[100]; char errbuf[100];
th_transport_t *t; th_transport_t *t;
char hostname[256]; char hostname[256];
int port; int port;
struct timespec ts;
int attempts = 0;
pthread_mutex_lock(&global_lock); pthread_mutex_lock(&global_lock);
@ -767,40 +769,48 @@ cwc_thread(void *aux)
pthread_mutex_lock(&global_lock); pthread_mutex_lock(&global_lock);
if(fd == -1) { if(fd == -1) {
attempts++;
tvhlog(LOG_INFO, "cwc", tvhlog(LOG_INFO, "cwc",
"Connection attempt to %s:%d failed: %s, retry in 3 seconds", "Connection attempt to %s:%d failed: %s",
hostname, port, errbuf); hostname, port, errbuf);
pthread_mutex_unlock(&global_lock); } else {
sleep(3);
pthread_mutex_lock(&global_lock);
continue;
}
if(cwc->cwc_running == 0) { if(cwc->cwc_running == 0) {
close(fd);
break;
}
tvhlog(LOG_INFO, "cwc", "Connected to %s:%d", hostname, port);
attempts = 0;
cwc->cwc_fd = fd;
cwc->cwc_reconfigure = 0;
cwc_session(cwc);
cwc->cwc_fd = -1;
close(fd); close(fd);
break; cwc->cwc_caid = 0;
tvhlog(LOG_INFO, "cwc", "Disconnected from %s", cwc->cwc_hostname);
} }
tvhlog(LOG_INFO, "cwc", "Connected to %s:%d", hostname, port); if(subscriptions_active()) {
if(attempts == 1)
continue; // Retry immediately
d = 3;
} else {
d = 60;
}
cwc->cwc_fd = fd; ts.tv_sec = time(NULL) + d;
cwc->cwc_reconfigure = 0; ts.tv_nsec = 0;
cwc_session(cwc); tvhlog(LOG_INFO, "cwc",
"%s: Automatic connection attempt in in %d seconds",
cwc->cwc_hostname, d);
cwc->cwc_fd = -1; pthread_cond_timedwait(&cwc_config_changed, &global_lock, &ts);
close(fd);
cwc->cwc_caid = 0;
tvhlog(LOG_INFO, "cwc", "Disconnected from %s, retry in %d seconds",
cwc->cwc_hostname, cwc->cwc_retry_delay);
pthread_mutex_unlock(&global_lock);
sleep(cwc->cwc_retry_delay);
pthread_mutex_lock(&global_lock);
cwc->cwc_retry_delay = cwc->cwc_retry_delay * 2 + 1;
if(cwc->cwc_retry_delay > 120)
cwc->cwc_retry_delay = 120;
} }
tvhlog(LOG_INFO, "cwc", "%s destroyed", cwc->cwc_hostname); tvhlog(LOG_INFO, "cwc", "%s destroyed", cwc->cwc_hostname);
@ -1197,6 +1207,8 @@ cwc_entry_update(void *opaque, const char *id, htsmsg_t *values, int maycreate)
pthread_cond_signal(&cwc->cwc_cond); pthread_cond_signal(&cwc->cwc_cond);
pthread_cond_broadcast(&cwc_config_changed);
return cwc_record_build(cwc); return cwc_record_build(cwc);
} }
@ -1210,6 +1222,8 @@ cwc_entry_delete(void *opaque, const char *id)
{ {
cwc_t *cwc; cwc_t *cwc;
pthread_cond_broadcast(&cwc_config_changed);
if((cwc = cwc_entry_find(id, 0)) == NULL) if((cwc = cwc_entry_find(id, 0)) == NULL)
return -1; return -1;
cwc_destroy(cwc); cwc_destroy(cwc);
@ -1255,6 +1269,7 @@ cwc_entry_get(void *opaque, const char *id)
static htsmsg_t * static htsmsg_t *
cwc_entry_create(void *opaque) cwc_entry_create(void *opaque)
{ {
pthread_cond_broadcast(&cwc_config_changed);
return cwc_record_build(cwc_entry_find(NULL, 1)); return cwc_record_build(cwc_entry_find(NULL, 1));
} }
@ -1286,6 +1301,8 @@ cwc_init(void)
TAILQ_INIT(&cwcs); TAILQ_INIT(&cwcs);
pthread_cond_init(&cwc_config_changed, NULL);
dt = dtable_create(&cwc_dtc, "cwc", NULL); dt = dtable_create(&cwc_dtc, "cwc", NULL);
dtable_load(dt); dtable_load(dt);
} }

View file

@ -39,7 +39,20 @@
struct th_subscription_list subscriptions; struct th_subscription_list subscriptions;
static gtimer_t subscription_reschedule_timer; static gtimer_t subscription_reschedule_timer;
/**
*
*/
int
subscriptions_active(void)
{
return LIST_FIRST(&subscriptions) != NULL;
}
/**
*
*/
static int static int
subscription_sort(th_subscription_t *a, th_subscription_t *b) subscription_sort(th_subscription_t *a, th_subscription_t *b)
{ {

View file

@ -68,4 +68,6 @@ void subscription_unlink_transport(th_subscription_t *s);
void subscription_dummy_join(const char *id); void subscription_dummy_join(const char *id);
int subscriptions_active(void);
#endif /* SUBSCRIPTIONS_H */ #endif /* SUBSCRIPTIONS_H */