Skip to content

Commit

Permalink
feat: add --profile flag to enable simpler debug profiling
Browse files Browse the repository at this point in the history
  • Loading branch information
edaniszewski committed Apr 14, 2020
1 parent 4514810 commit ad91f3a
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 1 deletion.
4 changes: 4 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,15 @@ RUN groupadd -g 51453 synse \
RUN apt-get update && apt-get install -y --no-install-recommends \
tini curl \
&& rm -rf /var/lib/apt/lists/* \
&& mkdir -p /synse \
&& mkdir -p /etc/synse \
&& chown -R synse:synse /synse \
&& chown -R synse:synse /etc/synse

COPY --from=builder /build /usr/local
COPY ./assets/favicon.ico /etc/synse/static/favicon.ico

USER synse
WORKDIR synse

ENTRYPOINT ["/usr/bin/tini", "--", "synse_server"]
35 changes: 34 additions & 1 deletion synse_server/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import argparse
import asyncio
import cProfile
import os
import sys

Expand Down Expand Up @@ -44,6 +45,10 @@ def main() -> None:
'--version', required=False, action='store_true',
help='print the version',
)
parser.add_argument(
'--profile', required=False, action='store_true',
help='profile synse server code execution,'
)
args = parser.parse_args()

if args.version:
Expand All @@ -54,7 +59,35 @@ def main() -> None:
host=args.host,
port=args.port,
)
server.run()

if args.profile:
print("""
*************************
Running in profiling mode
-------------------------
Synse Server was run with the --profile flag. This should only be used
for development/debug. It should not be used in production.
After Synse Server terminates, the profiling output will be printed out
to console and written to file (synse-server.profile). If running in a
container, it is your responsibility to copy the profile data out.
*************************
""")
pr = cProfile.Profile()
pr.enable()

try:
server.run()
except Exception as e:
print(f'Got exception: {e}')
finally:
pr.disable()

pr.print_stats('cumulative')
pr.dump_stats('synse-server.profile')

else:
server.run()


if __name__ == '__main__':
Expand Down
20 changes: 20 additions & 0 deletions synse_server/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
"""

import asyncio
import functools
import os
import signal
import sys

from structlog import get_logger
Expand Down Expand Up @@ -118,6 +120,15 @@ def _initialize(self) -> None:

def run(self) -> None:
"""Run Synse Server."""

# Register signals for graceful termination
for sig in ('SIGINT', 'SIGTERM'):
logger.info('adding signal handler to synse loop')
loop.synse_loop.add_signal_handler(
sig=getattr(signal, sig),
callback=functools.partial(_handle_signal, sig, loop.synse_loop),
)

logger.info('running synse server')

# If we are configured to log the header, write it to stdout instead
Expand Down Expand Up @@ -202,3 +213,12 @@ def reload_config(self) -> None:
# Load and validate the configuration values.
config.options.parse(requires_cfg=False)
config.options.validate()


def _handle_signal(signame, loop):
"""Handler function for when the Synse loop receives a registered signal.
This indicates that the server should shut down gracefully.
"""
logger.info('received termination signal, stopping loop', signal=signame, loop=loop)
loop.stop()

0 comments on commit ad91f3a

Please sign in to comment.