1a1083fa44a7ab4dafdc6d241cc9407a5a9faa81
David Blume first commit.

David Blume authored 5 years ago

1) # python_pinger
2) 
3) These are different approaches to how one might implement a daemon to
4) repeatedly ping multiple hosts to see if the network is up.
5) 
6) ## Single Threaded
7) 
8) This is the most naive implementation. For each ping host, the main
9) process thread pings them one at a time, and prints any changes.
10) 
David Blume Update the README.md with b...

David Blume authored 5 years ago

11) ![Single Threaded Pings](http://dlma.com/images/python_pinger/ping_single_threaded.png)
12) 
David Blume Minor README.md update

David Blume authored 5 years ago

13) The code for such a loop might look like this:
14) 
David Blume minor update to README

David Blume authored 5 years ago

15)     # "results" is a dict of ip_address -> last ping result
David Blume Minor README.md update

David Blume authored 5 years ago

16)     for address in results.keys():
17)         result = ping(address)
18)         if result != results[address]:
19)             log(f'{time.strftime("%Y-%m-%d %H:%M:%S", now)} {address} {result}')
20)             results[address] = result
21)     time.sleep(delay)
22) 
23) Logs go to a logfile, and example output looks like this:
24) 
25)     2019-07-06 11:23:20 192.168.1.1 UP
26)     2019-07-06 11:23:20 192.168.1.12 UP
27)     2019-07-06 11:23:29 192.168.1.12 DOWN
28)     2019-07-06 11:23:39 192.168.1.12 UP
David Blume first commit.

David Blume authored 5 years ago

29) 
30) ### Upsides
31) 
32) Really simple code.
33) 
34) ### Downsides
35) 
36) Since the pings are serialized, one long timeout from one host could
37) affect detecting a problem at another host.
38) 
David Blume Minor README.md update

David Blume authored 5 years ago

39) ## Long Lived Workers Consuming from a Queue
David Blume first commit.

David Blume authored 5 years ago

40) 
41) Raymond Hettinger's [PyBay 2018 Keynote](https://pybay.com/site_media/slides/raymond2017-keynote/threading.html)
David Blume Update the README.md a litt...

David Blume authored 5 years ago

42) uses the queue module to send data between threads, so I thought I'd make a
43) version of the pinger that did the same.
David Blume first commit.

David Blume authored 5 years ago

44) 
David Blume Update the README.md with b...

David Blume authored 5 years ago

45) ![Long Lived Queue Workers](http://dlma.com/images/python_pinger/ping_long_lived_queue_workers.png)
David Blume first commit.

David Blume authored 5 years ago

46) 
David Blume Update the README.md a litt...

David Blume authored 5 years ago

47) The main thread sends an address to a queue that the worker threads wait upon.
48) 
David Blume Update the README.md with b...

David Blume authored 5 years ago

49) See the source: **[long\_lived\_worker\_queue.py](http://git.dlma.com/python_pinger.git/blob/master/long_lived_worker_queue.py)**
David Blume first commit.

David Blume authored 5 years ago

50) 
51) ### Upsides
52) 
53) Multi-threaded ping calls won't block each other.
54) 
55) ### Downsides
56) 
David Blume Serialize the reading and w...

David Blume authored 5 years ago

57) The ping tasks read from, and write to a shared dictionary, so they need
58) to serialize that access.
David Blume first commit.

David Blume authored 5 years ago

59) 
60) ## Short Lived Workers
61) 
David Blume Add a version that uses a l...

David Blume authored 5 years ago

62) How about we don't keep the workers around, and only spawn them when
David Blume Update the README.md with b...

David Blume authored 5 years ago

63) there's something to do? That way, we won't waste memory when there's
David Blume Update the README.md a litt...

David Blume authored 5 years ago

64) nothing going on. The main thread passes the address to the workers when
65) they're constructed.
David Blume Update the README.md with b...

David Blume authored 5 years ago

66) 
67) ![Short Lived Workers](http://dlma.com/images/python_pinger/ping_short_lived_workers.png)
David Blume first commit.

David Blume authored 5 years ago

68) 
David Blume Update the README.md with b...

David Blume authored 5 years ago

69) See the source: **[short\_lived\_workers.py](http://git.dlma.com/python_pinger.git/blob/master/short_lived_workers.py)**
David Blume first commit.

David Blume authored 5 years ago

70) 
71) ### Upsides
72) 
73) The worker tasks aren't in memory if they're not doing anything. So usually a smaller memory profile.
74) 
75) ### Downsides
76) 
David Blume Serialize the reading and w...

David Blume authored 5 years ago

77) The ping tasks still read from, and write to that shared dictionary, so they serialize that access.
David Blume first commit.

David Blume authored 5 years ago

78) 
79) ## Long Lived Looping Workers
80) 
David Blume Update the README.md with b...

David Blume authored 5 years ago

81) I saved the best for last. The only thing the main thread does is bring the
82) workers and the print manager to life. The workers each independently do their own loop:
83) ping, compare, print, and wait.
84) 
David Blume Instead of having the proce...

David Blume authored 5 years ago

85) Since the process thread doesn't have anything to do after spawning the workers,
86) it can be one of the workers.
87) 
David Blume Update the README.md with b...

David Blume authored 5 years ago

88) ![Long Lived Looping Workers](http://dlma.com/images/python_pinger/ping_long_lived_looping_workers.png)
David Blume first commit.

David Blume authored 5 years ago

89) 
David Blume Update the README.md with b...

David Blume authored 5 years ago

90) See the source: **[long\_lived\_looping\_workers.py](http://git.dlma.com/python_pinger.git/blob/master/long_lived_looping_workers.py)**
David Blume first commit.

David Blume authored 5 years ago

91) 
92) ### Upsides
93) 
94) No more race conditions! The worker threads mind their own business.
95) 
96) ### Downsides
97) 
98) The worker threads remain in memory.
99) 
David Blume Add a version that uses a l...

David Blume authored 5 years ago

100) ## Long Lived Looping Locked Workers
101) 
102) That was fun using only the synchronized queue class and no locks. But now that
103) we've got the long lived looping workers that don't need their own queue, let's
104) replace the print manager with a threading lock.
105) 
106) ![Long Lived Looping Locked Workers](http://dlma.com/images/python_pinger/ping_long_lived_looping_locked_workers.png)
107) 
108) See the source: **[long\_lived\_looping\_locked\_workers.py](http://git.dlma.com/python_pinger.git/blob/master/long_lived_looping_locked_workers.py)**
109) 
110) ### Upsides
111) 
112) Got rid of the entire printer thread.
113) 
114) ### Downsides
115) 
116) Uses a lock, which in more complex applications with multiple locks becomes difficult to reason about.
117)