Skip to content

Instantly share code, notes, and snippets.

@mikofski
Created August 26, 2014 16:54
Show Gist options
  • Select an option

  • Save mikofski/e1e1b953cdf42f6170d4 to your computer and use it in GitHub Desktop.

Select an option

Save mikofski/e1e1b953cdf42f6170d4 to your computer and use it in GitHub Desktop.

Revisions

  1. mikofski created this gist Aug 26, 2014.
    115 changes: 115 additions & 0 deletions memcached_service.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,115 @@
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    #
    # Attribution: Hijacked from tracservice.py by Florent Xicluna <[email protected]>
    # http://trac-hacks.org/wiki/WindowsServiceScript
    #
    # To use this class, users must do the following:
    # 1. Download and install the PyWin32all package
    # (http://starship.python.net/crew/mhammond/win32/)
    # 2. Edit the constants section with the proper information.
    # 3. Open a command prompt with administrator rights and navigate to the directory
    # where this file is located. Use one of the following commands to
    # install/start/stop/remove the service:
    # > memcached_service.py install
    # > memcached_service.py start
    # > memcached_service.py stop
    # > memcached_service.py remove
    # Additionally, typing "memcached_service.py" will present the user with all of the
    # available options.
    #
    # Once installed, the service will be accessible through the Services
    # management console just like any other Windows Service. All service
    # startup exceptions encountered by the MemcachedWindowsService class will be
    # viewable in the Windows event viewer (this is useful for debugging
    # service startup errors); all application specific output or exceptions that
    # are not captured by the standard memcached logging mechanism should
    # appear in the stdout/stderr logs.
    #

    import os
    import subprocess
    import json
    import win32serviceutil
    import win32service
    import win32event
    import logging

    MEMCACHED_OPTS_FILE = 'memcached_opts.json'
    MEMCACHED_EXE = 'memcached.exe'
    MEMCACHED_LOG = 'memcache.log'
    DIRNAME = os.path.dirname(__file__)
    logging.basicConfig(filename=os.path.join(DIRNAME, MEMCACHED_LOG),
    level=logging.DEBUG, format='[%(asctime)s] %(levelname)s: %(message)s')
    MEMCACHED = os.path.join(DIRNAME, MEMCACHED_EXE)
    OPTS_FILE = os.path.join(DIRNAME, MEMCACHED_OPTS_FILE)
    if os.path.exists(OPTS_FILE):
    with open(OPTS_FILE, 'r') as opts_file:
    OPTS = json.load(opts_file)

    # memcached args
    ARGS = [MEMCACHED]
    # ARGS += [arg for key_val in OPTS.iteritmes() for arg in key_val]

    class MemcachedWindowsService(win32serviceutil.ServiceFramework):
    """memcached Windows Service helper class.
    The MemcachedWindowsService class contains all the functionality required
    for running memcached application as a Windows Service.
    For information on installing the application, please refer to the
    documentation at the end of this module or navigate to the directory
    where this module is located and type "memcached_service.py" from the
    command prompt.
    """

    _svc_name_ = 'memcached'
    _svc_display_name_ = 'memcached server at %s' % MEMCACHED

    def __init__(self, args):
    win32serviceutil.ServiceFramework.__init__(self, args)
    # create an event that SvcDoRun can wait on and SvcStop
    # can set.
    self.stop_event = win32event.CreateEvent(None, 0, 0, None)

    def SvcDoRun(self):
    """ Called when the Windows Service runs. """

    self.ReportServiceStatus(win32service.SERVICE_START_PENDING)
    try:
    self.popen = subprocess.Popen(ARGS)
    except Exception as err:
    logging.debug('%s', err.message)
    raise err
    if not self.popen.returncode:
    logging.debug('memcached service started on PID: %d',
    self.popen.pid)
    else:
    logging.debug('memcached service failed to start')

    self.ReportServiceStatus(win32service.SERVICE_RUNNING)
    # now, block until our event is set...
    win32event.WaitForSingleObject(self.stop_event, win32event.INFINITE)

    def SvcStop(self):
    """Called when Windows receives a service stop request."""

    self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
    self.popen.kill()
    logging.debug('memcached service stopped on PID: %d', self.popen.pid)

    self.ReportServiceStatus(win32service.SERVICE_STOPPED)
    win32event.SetEvent(self.stop_event)


    if __name__ == '__main__':
    # The following are the most common command-line arguments that are used
    # with this module:
    # memcached_service.py install (Installs the service with manual startup)
    # memcached_service.py --startup auto install (Installs the service with auto startup)
    # memcached_service.py start (Starts the service)
    # memcached_service.py stop (Stops the service)
    # memcached_service.py remove (Removes the service)
    #
    # For a full list of arguments, simply type "memcached_service.py".
    win32serviceutil.HandleCommandLine(MemcachedWindowsService)