| 
									
										
										
										
											2017-01-31 12:42:05 +01:00
										 |  |  | package signal | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"context" | 
					
						
							|  |  |  | 	"time" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-27 15:29:00 +02:00
										 |  |  | type ActivityUpdater interface { | 
					
						
							| 
									
										
										
										
											2017-04-04 10:24:38 +02:00
										 |  |  | 	Update() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-27 15:29:00 +02:00
										 |  |  | type ActivityTimer struct { | 
					
						
							| 
									
										
										
										
											2017-01-31 12:42:05 +01:00
										 |  |  | 	updated chan bool | 
					
						
							| 
									
										
										
										
											2017-09-27 15:29:00 +02:00
										 |  |  | 	timeout chan time.Duration | 
					
						
							| 
									
										
										
										
											2017-01-31 12:42:05 +01:00
										 |  |  | 	ctx     context.Context | 
					
						
							|  |  |  | 	cancel  context.CancelFunc | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-27 15:29:00 +02:00
										 |  |  | func (t *ActivityTimer) Update() { | 
					
						
							| 
									
										
										
										
											2017-01-31 12:42:05 +01:00
										 |  |  | 	select { | 
					
						
							|  |  |  | 	case t.updated <- true: | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-27 15:29:00 +02:00
										 |  |  | func (t *ActivityTimer) SetTimeout(timeout time.Duration) { | 
					
						
							|  |  |  | 	t.timeout <- timeout | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (t *ActivityTimer) run() { | 
					
						
							|  |  |  | 	ticker := time.NewTicker(<-t.timeout) | 
					
						
							| 
									
										
										
										
											2017-10-06 15:42:46 +08:00
										 |  |  | 	defer func() { | 
					
						
							|  |  |  | 		ticker.Stop() | 
					
						
							|  |  |  | 	}() | 
					
						
							| 
									
										
										
										
											2017-05-08 17:09:21 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-31 12:42:05 +01:00
										 |  |  | 	for { | 
					
						
							|  |  |  | 		select { | 
					
						
							| 
									
										
										
										
											2017-05-08 17:09:21 +02:00
										 |  |  | 		case <-ticker.C: | 
					
						
							| 
									
										
										
										
											2017-01-31 12:42:05 +01:00
										 |  |  | 		case <-t.ctx.Done(): | 
					
						
							|  |  |  | 			return | 
					
						
							| 
									
										
										
										
											2017-09-27 15:29:00 +02:00
										 |  |  | 		case timeout := <-t.timeout: | 
					
						
							|  |  |  | 			ticker.Stop() | 
					
						
							|  |  |  | 			ticker = time.NewTicker(timeout) | 
					
						
							| 
									
										
										
										
											2017-01-31 14:15:34 +01:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-05-08 17:09:21 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-31 14:15:34 +01:00
										 |  |  | 		select { | 
					
						
							|  |  |  | 		case <-t.updated: | 
					
						
							|  |  |  | 		// Updated keep waiting. | 
					
						
							| 
									
										
										
										
											2017-01-31 12:42:05 +01:00
										 |  |  | 		default: | 
					
						
							| 
									
										
										
										
											2017-01-31 14:15:34 +01:00
										 |  |  | 			t.cancel() | 
					
						
							|  |  |  | 			return | 
					
						
							| 
									
										
										
										
											2017-01-31 12:42:05 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-15 00:36:14 +01:00
										 |  |  | func CancelAfterInactivity(ctx context.Context, cancel context.CancelFunc, timeout time.Duration) *ActivityTimer { | 
					
						
							| 
									
										
										
										
											2017-09-27 15:29:00 +02:00
										 |  |  | 	timer := &ActivityTimer{ | 
					
						
							| 
									
										
										
										
											2017-01-31 12:42:05 +01:00
										 |  |  | 		ctx:     ctx, | 
					
						
							|  |  |  | 		cancel:  cancel, | 
					
						
							| 
									
										
										
										
											2017-09-27 15:29:00 +02:00
										 |  |  | 		timeout: make(chan time.Duration, 1), | 
					
						
							| 
									
										
										
										
											2017-01-31 12:42:05 +01:00
										 |  |  | 		updated: make(chan bool, 1), | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-09-27 15:29:00 +02:00
										 |  |  | 	timer.timeout <- timeout | 
					
						
							| 
									
										
										
										
											2017-01-31 12:42:05 +01:00
										 |  |  | 	go timer.run() | 
					
						
							| 
									
										
										
										
											2017-11-15 00:36:14 +01:00
										 |  |  | 	return timer | 
					
						
							| 
									
										
										
										
											2017-01-31 12:42:05 +01:00
										 |  |  | } |