* 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:
parent
1e5631c81d
commit
7cab70e1e5
4 changed files with 67 additions and 27 deletions
8
debian/changelog
vendored
8
debian/changelog
vendored
|
@ -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
|
||||||
|
|
71
src/cwc.c
71
src/cwc.c
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Add table
Reference in a new issue