Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add example of running multiple zerogw on single socket/port/fd
- Loading branch information
Showing
4 changed files
with
149 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#!/usr/bin/env python3 | ||
|
||
""" | ||
This script is intended to run multiple zerogw instances with single shared | ||
port/socket. This works by creating a socket externally, and pasing it as | ||
a file descriptor to all zerogw instances, during exec. | ||
You must configure zerogw to use the file descriptor to run correctly | ||
(example zerogw_fd.yaml does this) | ||
""" | ||
|
||
import socket | ||
import os | ||
import sys | ||
|
||
# Let's open shared socket | ||
zgwsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | ||
zgwsock.bind(('0.0.0.0', 8000)) | ||
zgwsock.listen(100000) | ||
zgwsock.setblocking(False) # Crucial for zerogw with older libwebsite | ||
|
||
# Now make it file descriptor zero | ||
os.dup2(zgwsock.fileno(), 0) | ||
|
||
# Now close old socket (we have dup as fd zero) | ||
zgwsock.close() | ||
|
||
# Each zerogw has it's own socket directory, so we use pass directory | ||
# names as arguments and create a zerogw instance per directory | ||
for dir in sys.argv[1:]: | ||
if dir != sys.argv[-1]: # last instance is our process, no more forks | ||
if os.fork(): # parent continues to fork processes | ||
continue | ||
os.execlp('zerogw', 'zerogw', '-c', 'zerogw_fd.yaml', '-Ddir=' + dir) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
#!/bin/sh | ||
|
||
# Setting up signal handlers | ||
# All this code is needed to do not leave dangling children | ||
killchildren() { | ||
if [ "x$(jobs)" == "x" ]; then | ||
exit 0 | ||
fi | ||
trap killchildren 0 1 2 3 15 | ||
kill $(jobs -p) 2>/dev/null | ||
} | ||
trap killchildren 0 1 2 3 15 | ||
|
||
# running several redis instances is given as exercise for the reader | ||
# basically you just need more python code for that | ||
redis-server redis.conf & | ||
|
||
# We provide each zerogw instance a separate directory for zeromq sockets | ||
# because zeromq sockets are bound, but use special startup script for | ||
# running them on single port | ||
mkdir -p ./run/z{1,2,3} 2> /dev/null | ||
# passing three dirs means start three zerogw instances one per dir | ||
python single_port_zerogw.py ./run/z1 ./run/z2 ./run/z3 & | ||
|
||
# because of zeromq features, and because we are using bind sockets in zerogw | ||
# side (which is most useful use case), we can run any number of backends | ||
# with equal configuration | ||
# BTW, storing data in redis also helps | ||
for i in $(seq 0 4); do | ||
python3 -m tabbedchat \ | ||
--auth-connect "ipc://./run/z1/auth.sock" \ | ||
--auth-connect "ipc://./run/z2/auth.sock" \ | ||
--auth-connect "ipc://./run/z3/auth.sock" \ | ||
--chat-connect "ipc://./run/z1/chat.sock" \ | ||
--chat-connect "ipc://./run/z2/chat.sock" \ | ||
--chat-connect "ipc://./run/z3/chat.sock" \ | ||
--output-connect "ipc://./run/z1/output.sock" \ | ||
--output-connect "ipc://./run/z2/output.sock" \ | ||
--output-connect "ipc://./run/z3/output.sock" \ | ||
& | ||
done | ||
|
||
echo "========================================================================" | ||
echo "You can now browse:" | ||
echo " http://localhost:8000/" | ||
echo "Depending on your luck you will hit different zerogw instance each time" | ||
echo "NOTE: Long polling (websocket fallback) doesn't work correctly" | ||
echo "WARNING: Danging zerogw processes may exist after stopping" | ||
echo "========================================================================" | ||
|
||
while ! wait; do true; done; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
# This is example of configuration file with listening socket passed by | ||
# file descriptor. It's useful to bind to port 80 either using openport or | ||
# using procboss, and to run multiple instances of zerogw on single port | ||
# (see single_socket.sh) | ||
|
||
# Zerogw's configuration library allows you to override variables | ||
# from a command line, so we create one, to be able to override port and socket | ||
# directory. See ./scale.sh for example of how to use it | ||
# (we use yaml anchors and $-style variables interchangeably with coyaml) | ||
_dir: &dir ./run | ||
|
||
Server: | ||
zmq-io-threads: 1 | ||
disk-io-threads: 1 | ||
listen: | ||
- host: 0.0.0.0 | ||
port: 8000 | ||
fd: 0 # File descriptor number zero is used instead of host/port | ||
control: | ||
socket: | ||
- !zmq.Bind ipc://$dir/zerogw-ctl | ||
error-log: | ||
level: 3 | ||
warning-timeout: 300 | ||
filename: ./run/error.log | ||
|
||
Routing: | ||
routing: !Prefix ~ | ||
routing-by: !Uri ~ | ||
map: | ||
"/": | ||
static: | ||
enabled: yes | ||
root: ./public | ||
restrict-root: no # bad for production | ||
index-file: index.html | ||
"/ws*": | ||
websocket: | ||
enabled: yes | ||
forward: !zmq.Push | ||
- !zmq.Bind "ipc://$dir/auth.sock" | ||
named-outputs: | ||
chat: !zmq.Push | ||
sync-interval: 10 # too low, for example purposes | ||
=: | ||
- !zmq.Bind "ipc://$dir/chat.sock" | ||
subscribe: !zmq.Pull | ||
- !zmq.Bind "ipc://$dir/output.sock" | ||
children: | ||
- match: | ||
- "/js/*" | ||
- "/css/*" | ||
static: | ||
enabled: yes | ||
root: ./public | ||
restrict-root: no # bad for production |