Skip to content
This repository has been archived by the owner on Jul 13, 2023. It is now read-only.

Commit

Permalink
feat: initial Rust proof of concept implementation
Browse files Browse the repository at this point in the history
Implements a complete Rust proof of concept Push server using a queue
to send future calls to complete to a Python threaded server. The
Python side contains an extraction of the websocket logic, following
an intended call pattern documented in states.dot.

Co-Authored-By: Alex Crichton <[email protected]>
Co-Authored-By: Philip Jenvey <[email protected]>

Closes #978
  • Loading branch information
bbangert committed Sep 6, 2017
1 parent dc33966 commit 5bf2de6
Show file tree
Hide file tree
Showing 27 changed files with 4,892 additions and 2 deletions.
2 changes: 2 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ omit =
*noseplugin*
autopush/tests/certs/makecerts.py
autopush/gcdump.py
autopush/webpush_server.py
autopush/tests/test_webpush_server.py
show_missing = true
8 changes: 7 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
language: python
cache: pip
cache:
directories:
- $HOME/.cargo
- autopush_rs/target
- $HOME/.cache/pip
sudo: required
dist: trusty

Expand All @@ -22,6 +26,8 @@ before_install:
install:
- ${DDB:+make ddb}
- pip install tox ${CODECOV:+codecov}
- curl https://sh.rustup.rs | sh -s -- -y
- export PATH=$PATH:$HOME/.cargo/bin
script:
- tox -- ${CODECOV:+--with-coverage --cover-xml --cover-package=autopush}
after_success:
Expand Down
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ RUN mkdir -p /app
ADD . /app

WORKDIR /app
ENV PATH=$PATH:/root/.cargo/bin

RUN \
apt-get update && \
apt-get install -y -qq libexpat1-dev gcc libssl-dev libffi-dev && \
curl https://sh.rustup.rs | sh -s -- -y && \
make clean && \
pip install -r requirements.txt && \
pypy setup.py develop
Expand Down
2 changes: 2 additions & 0 deletions Dockerfile.python27
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ RUN mkdir -p /app
COPY . /app

WORKDIR /app
ENV PATH=$PATH:/root/.cargo/bin

RUN \
apt-get update && \
apt-get install -y -qq libexpat1-dev gcc libssl-dev libffi-dev && \
curl https://sh.rustup.rs | sh -s -- -y && \
make clean && \
pip install -r requirements.txt && \
python setup.py develop
Expand Down
92 changes: 92 additions & 0 deletions autopush/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
from autopush.logging import PushLogger
from autopush.main_argparse import parse_connection, parse_endpoint
from autopush.router import routers_from_config
from autopush.webpush_server import WebPushServer
from autopush.websocket import (
ConnectionWSSite,
PushServerFactory,
Expand Down Expand Up @@ -287,3 +288,94 @@ def from_argparse(cls, ns):
max_connections=ns.max_connections,
close_handshake_timeout=ns.close_handshake_timeout,
)


class RustConnectionApplication(AutopushMultiService):
"""The autopush application"""

config_files = AutopushMultiService.shared_config_files + (
'/etc/autopush_connection.ini',
'configs/autopush_connection.ini',
'~/.autopush_connection.ini',
'.autopush_connection.ini'
)

parse_args = staticmethod(parse_connection) # type: ignore
logger_name = "AutopushRust"
push_server = None

def __init__(self, conf):
# type: (AutopushConfig) -> None
super(RustConnectionApplication, self).__init__(conf)

def setup(self, rotate_tables=True):
self.db.setup(self.conf.preflight_uaid)

if self.conf.memusage_port:
self.add_memusage()

self.push_server = WebPushServer(self.conf, self.db, num_threads=10)

def run(self):
try:
self.push_server.run()
finally:
self.stopService()

@inlineCallbacks
def stopService(self):
yield super(RustConnectionApplication, self).stopService()

@classmethod
def from_argparse(cls, ns):
# type: (Namespace) -> AutopushMultiService
return super(RustConnectionApplication, cls)._from_argparse(
ns,
port=ns.port,
endpoint_scheme=ns.endpoint_scheme,
endpoint_hostname=ns.endpoint_hostname,
endpoint_port=ns.endpoint_port,
router_scheme="https" if ns.router_ssl_key else "http",
router_hostname=ns.router_hostname,
router_port=ns.router_port,
env=ns.env,
hello_timeout=ns.hello_timeout,
router_ssl=dict(
key=ns.router_ssl_key,
cert=ns.router_ssl_cert,
dh_param=ns.ssl_dh_param
),
# XXX: default is for autopush_rs
auto_ping_interval=ns.auto_ping_interval or 300,
auto_ping_timeout=ns.auto_ping_timeout,
max_connections=ns.max_connections,
close_handshake_timeout=ns.close_handshake_timeout,
)

@classmethod
def main(cls, args=None, use_files=True):
# type: (Sequence[str], bool) -> Any
"""Entry point to autopush's main command line scripts.
aka autopush/autoendpoint.
"""
ns = cls.parse_args(cls.config_files if use_files else [], args)
if not ns.no_aws:
logging.HOSTNAME = utils.get_ec2_instance_id()
PushLogger.setup_logging(
cls.logger_name,
log_level=ns.log_level or ("debug" if ns.debug else "info"),
log_format="text" if ns.human_logs else "json",
log_output=ns.log_output,
sentry_dsn=bool(os.environ.get("SENTRY_DSN")),
firehose_delivery_stream=ns.firehose_stream_name
)
try:
app = cls.from_argparse(ns)
except InvalidConfig as e:
log.critical(str(e))
return 1

app.setup()
app.run()
Loading

0 comments on commit 5bf2de6

Please sign in to comment.