Beispiel #1
0
    def send_binary_to_socket_with_signal(self, signaled_buffer):
        """
        Send to socket, asynch.
        Upon completion, signaled_buffer.send_event is set.
        Caution : Caller MUST check the boolean returned. If False, the event will NOT be set.
        :param signaled_buffer: A signaled_buffer instance.
        :type signaled_buffer: pysoltcp.tcpbase.SignaledBuffer.SignaledBuffer
        :return: True is send has been scheduled, false otherwise.
        :rtype bool
        """

        # Check
        if not isinstance(signaled_buffer, SignaledBuffer):
            logger.error("signaled_buffer not a SignaledBuffer, class=%s, self=%s", SolBase.get_classname(signaled_buffer), self)
            return False

            # Check
        if not isinstance(signaled_buffer.binary_buffer, binary_type):
            logger.error("binary_buffer not a binary, class=%s, self=%s", SolBase.get_classname(signaled_buffer.binary_buffer), self)
            return False

        # Check
        if not self.__is_running():
            logger.debug(
                "not connected, returning false, self=%s",
                self)
            return False

        # Enqueue
        self.__send_queue.put(signaled_buffer)

        # Stats
        Meters.aii("tcp.server.server_bytes_send_pending", len(signaled_buffer.binary_buffer))

        return True
    def __init__(self, hello_timeout_ms, ping_interval_ms, ping_timeout_ms):
        """
        Constructor.
        :param hello_timeout_ms: Timeout in millis.
        :param ping_interval_ms: Timeout in millis.
        :param ping_timeout_ms: Timeout in millis.
        """

        self._hello_timeout_ms = SolBase.to_int(hello_timeout_ms)
        self._ping_interval_ms = SolBase.to_int(ping_interval_ms)
        self._ping_timeout_ms = SolBase.to_int(ping_timeout_ms)

        logger.info("_hello_timeout_ms=%s, type=%s", self._hello_timeout_ms, SolBase.get_classname(self._hello_timeout_ms))
        logger.info("_ping_interval_ms=%s, type=%s", self._ping_interval_ms, SolBase.get_classname(self._ping_interval_ms))
        logger.info("_ping_timeout_ms=%s, type=%s", self._ping_timeout_ms, SolBase.get_classname(self._ping_timeout_ms))
Beispiel #3
0
    def _internal_init(self,
                       pidfile,
                       stdin,
                       stdout,
                       stderr,
                       logfile,
                       loglevel,
                       on_start_exit_zero,
                       max_open_files,
                       change_dir,
                       timeout_ms,
                       logtosyslog=True,
                       logtosyslog_facility=SysLogHandler.LOG_LOCAL0,
                       logtoconsole=True,
                       app_name="Test"):

        # Us
        self.is_running = True
        self.start_count = 0
        self.stop_count = 0
        self.reload_count = 0
        self.status_count = 0
        self.start_loop_exited = Event()
        self.last_action = "noaction"

        # Base
        Daemon._internal_init(self, pidfile, stdin, stdout, stderr, logfile,
                              loglevel, on_start_exit_zero, max_open_files,
                              change_dir, timeout_ms, logtosyslog,
                              logtosyslog_facility, logtoconsole, app_name)

        # Log
        logger.debug("Done, self.class=%s", SolBase.get_classname(self))
Beispiel #4
0
    def parse_arguments(cls, argv):
        """
        Parse command line argument (initParser required before call)
        :param cls: Our class.
        :param argv: Command line argv
        :type argv: list, tuple
        :return dict
        :rtype dict
        """

        logger.debug("Entering")

        # Check argv
        if not isinstance(argv, (tuple, list)):
            raise Exception("parse_arguments : argv not a list, class=%s" +
                            SolBase.get_classname(argv))

        # Parse
        local_args = cls.initialize_arguments_parser().parse_args(argv)

        # Flush
        d = vars(local_args)
        logger.debug("Having vars=%s", d)

        return d
Beispiel #5
0
    def send_binary_to_socket(self, buffer_to_send):
        """
        Send to socket, asynch.
        :param buffer_to_send: The localBuffer to send (bytes)
        :type buffer_to_send: bytes
        :return: True is send has been scheduled, false otherwise.
        :rtype bool
        """

        # Check
        if not isinstance(buffer_to_send, binary_type):
            logger.error("buffer_to_send not a binary, class=%s, self=%s", SolBase.get_classname(buffer_to_send), self)
            return False

        # Check
        if not self.__is_running():
            logger.debug("not connected, returning false, self=%s", self)
            return False

        # Enqueue
        self.__send_queue.put(buffer_to_send)

        # Stats
        Meters.aii("tcp.server.server_bytes_send_pending", len(buffer_to_send))

        return True
Beispiel #6
0
    def _set_stop_server_timeout_ms(self, ms):
        """
        Setter. Raise exception if a problem occurs.
        :param ms: Time out in ms.
        :type ms: int
        """

        cms = SolBase.to_int(ms)
        if not SolBase.is_int(cms):
            logger.error("not a int, class=%s", SolBase.get_classname(cms))
            raise Exception("not a int")
        else:
            self._stop_server_timeout_ms = cms
Beispiel #7
0
    def _set_auto_start(self, b):
        """
        Getter
        :param b: A boolean.
        :type b: bool
        """

        mb = SolBase.to_bool(b)

        if not SolBase.is_bool(mb):
            logger.error("not a boolean, class=%s", SolBase.get_classname(mb))
            raise Exception("not a boolean")
        else:
            self._auto_start = mb
Beispiel #8
0
    def _set_onstop_call_client_stopsynch(self, b):
        """
        Getter
        :param b: A boolean.
        :type b: bool
        """

        mb = SolBase.to_bool(b)

        if not SolBase.is_bool(mb):
            logger.error("not a boolean, class=%s", SolBase.get_classname(mb))
            raise Exception("not a boolean")
        else:
            self._onstop_callclient_stopsynch = mb
Beispiel #9
0
    def _set_ssl_enable(self, b):
        """
        Enable or disable ssl.
        :param b: Boolean.
        :type b: bool
        """

        is_enable = SolBase.to_bool(b)

        if not SolBase.is_bool(is_enable):
            logger.error("not a boolean, class=%s",
                         SolBase.get_classname(is_enable))
            raise Exception("not a boolean")
        else:
            self._ssl_enable = is_enable
Beispiel #10
0
 def _set_target_port(self, target_port):
     """
     Setter. Raise exception if a problem occurs.
     :param target_port: The target port.
     :type target_port: int
     """
     if not SolBase.is_int(target_port):
         logger.error(
             "TcpClientConfig : _set_target_port : not a int, class=%s",
             SolBase.get_classname(target_port))
         raise Exception("TcpClientConfig : _set_target_port : not a int")
     elif target_port == 0:
         logger.warning("TcpClientConfig : _set_target_port : newPort==0")
         raise Exception("TcpClientConfig : _set_target_port : newPort==0")
     else:
         self._target_port = target_port
Beispiel #11
0
    def _set_child_process_count(self, cpc):
        """
        Setter. Raise exception if a problem occurs.
        :param cpc: The number of child process count. If zero, no fork is performed (default).
        :type cpc: int
        """

        child_process_count = SolBase.to_int(cpc)

        if not SolBase.is_int(child_process_count):
            logger.error("not a int, class=%s",
                         SolBase.get_classname(child_process_count))
            raise Exception("not a int")
        elif child_process_count < 0:
            logger.warning("child_process_count<0")
            raise Exception("child_process_count<0")
        else:
            self._child_process_count = child_process_count
Beispiel #12
0
    def _set_listen_port(self, listen_port):
        """
        Setter. Raise exception if a problem occurs.
        :param listen_port: The listen port.
        :type listen_port: int
        """

        listen_port = SolBase.to_int(listen_port)

        if not SolBase.is_int(listen_port):
            logger.error("not a int, class=%s",
                         SolBase.get_classname(listen_port))
            raise Exception("not a int")
        elif listen_port == 0:
            logger.warning("newPort==0")
            raise Exception("newPort==0")
        else:
            self._listen_port = listen_port
Beispiel #13
0
    def is_dir_exist(dir_name):
        """
        Check if dir name exist.
        :param dir_name: Directory name.
        :type dir_name: str
        :return: Return true (exist), false (do not exist, or invalid file name)
        :rtype bool
        """

        # Check
        if dir_name is None:
            logger.error("is_dir_exist : file_name is None")
            return False
        elif not isinstance(dir_name, str):
            logger.error(
                "is_dir_exist : file_name not a text_type, className=%s",
                SolBase.get_classname(dir_name))
            return False

        # Go
        return os.path.isdir(dir_name)
Beispiel #14
0
    def is_path_exist(path_name):
        """
        Check if a path (file or dir) name exist.
        :param path_name: Path name.
        :type path_name text_type
        :return: Return true (exist), false (do not exist, or invalid file name)
        :rtype bool
        """

        # Check
        if path_name is None:
            logger.error("is_path_exist : file_name is None")
            return False
        elif not isinstance(path_name, str):
            logger.error(
                "is_path_exist : path_name not a text_type, className=%s",
                SolBase.get_classname(path_name))
            return False

        # Go
        return os.path.exists(path_name)
Beispiel #15
0
 def _set_tcpkeepalive_probes_sendintervalms(self, value):
     """
     Setter. Raise exception if a problem occurs.
     :param value: Value.
     :type value: int
     
     """
     if not SolBase.is_int(value):
         logger.error(
             "TcpClientConfig : _set_tcpkeepalive_probes_sendintervalms : not a int, class=%s",
             SolBase.get_classname(value))
         raise Exception(
             "TcpClientConfig : _set_tcpkeepalive_probes_sendintervalms : not a int"
         )
     elif value == 0:
         logger.warning(
             "TcpClientConfig : _set_tcpkeepalive_probes_sendintervalms : newPort==0"
         )
         raise Exception(
             "TcpClientConfig : _set_tcpkeepalive_probes_sendintervalms : newPort==0"
         )
     else:
         self._tcp_keepalive_probes_sendintervalms = value
Beispiel #16
0
    def _write_loop_internal(self):
        """
        Low level read/write loop on socket
        """
        logger.debug("entering now, self=%s", self)
        try:
            while self.__is_running():
                try:
                    # Wait for the queue
                    try:
                        # Call, with blocking.
                        item = self.send_queue.get(True, TcpSocketManager.QUEUE_WAIT_SEC_PER_LOOP)

                    except Empty:
                        # Next read
                        SolBase.sleep(0)
                        continue

                    # Go some
                    if isinstance(item, binary_type):
                        # Length
                        length = len(item)
                        # Buffer to send
                        buf_to_send = item
                        # Event to signal
                        event_to_signal = None
                    elif isinstance(item, SignaledBuffer):
                        # Stats
                        length = len(item.binary_buffer)
                        # Buffer to send
                        buf_to_send = item.binary_buffer
                        # Event to signal
                        event_to_signal = item.send_event
                    else:
                        logger.warning("not managed class in queue, class=%s, item=%s", SolBase.get_classname(item), item)
                        continue

                    # Stat now
                    Meters.aii("tcp.server.server_bytes_send_pending", -length)

                    # Wait for socket to be available for write
                    logger.debug("waiting for socket to send=%s, self=%s", repr(item), self)
                    ok = self._wait_for_socket_send()
                    if not ok:
                        # This is not really normal
                        if self.__is_running():
                            logger.warning("_wait_for_socket_send returned False (running true), self=%s", self)
                        else:
                            logger.info("_wait_for_socket_send returned False (running false), self=%s", self)
                    elif not self.__is_running():
                        logger.debug("Ready for send, but __is_running==False, exiting, send=%s, self=%s", self)
                        return
                    else:
                        try:
                            # Ready to write, fire
                            logger.debug("writing to socket to send=%s, self=%s", repr(item), self)
                            ok = self._write_to_socket(buf_to_send)
                            if not ok:
                                if self.__is_running():
                                    # This is not really normal
                                    logger.warning("_write_to_socket returned False (running true), self=%s", self)
                                else:
                                    logger.warning("_write_to_socket returned False (running false), self=%s", self)

                            # Signal if applicable
                            if event_to_signal:
                                event_to_signal.set()
                        finally:
                            # Timestamps
                            self._dt_last_send = SolBase.datecurrent()

                            # Stats
                            Meters.aii("tcp.server.server_bytes_send_done", length)

                    # Next read
                    SolBase.sleep(0)
                except Exception as e:
                    logger.warning("IN_LOOP Exception raised, ex=%s, self=%s", SolBase.extostr(e), self)
        except Exception as e:
            logger.error("METHOD Exception raised, ex=%s, self=%s", SolBase.extostr(e), self)
        finally:
            logger.debug("exiting now, self=%s", self)
            SolBase.sleep(0)
Beispiel #17
0
    def send_unicode_to_socket(self, unicode_to_send, encoding="utf-8", append_lf=True):
        """
        Send text to socket, asynch.
        :param unicode_to_send: The text to send (str)
        :type unicode_to_send: str
        :param encoding: The encoding to use.
        :type encoding: str
        :param append_lf: If true, append an \n
        :type append_lf: bool
        :return: True is send has been scheduled, false otherwise.
        :rtype: bool
        """

        # Check
        if not isinstance(unicode_to_send, string_types):
            logger.error("unicode_to_send not an string_types, class=%s, str=%s, self=%s", SolBase.get_classname(unicode_to_send), repr(unicode_to_send), self)
            return False

        # Go
        unicode_temp = unicode_to_send

        # LF if required
        if append_lf:
            unicode_temp += u"\n"

        # Convert to binary localBuffer
        bin_buf = SolBase.unicode_to_binary(unicode_temp, encoding)

        # Send binary
        return self.send_binary_to_socket(bin_buf)
Beispiel #18
0
    def __init__(self, tcp_server_config):
        """
        Constructor.
        :param tcp_server_config: The configuration.
        :type tcp_server_config: pysoltcp.tcpserver.TcpServerConfig.TcpServerConfig
        """

        # Check
        if tcp_server_config is None:
            logger.error("tcp_server_config is None")
            raise Exception("tcp_server_config is None")
        elif not isinstance(tcp_server_config, TcpServerConfig):
            logger.error(
                "tcp_server_config is not a TcpServerConfig, class=%s",
                SolBase.get_classname(tcp_server_config))
            raise Exception("tcp_server_config is not a TcpServerConfig")

        # Store
        self._tcp_server_config = tcp_server_config

        # Init =>

        # _is_started :
        # - True if server is started, False is server is stopped.
        # - Start : try to start, if ok set to True
        # - Stop : stop server, stop client, and set to False
        # - Means : During stop ongoing, will be True
        self._is_started = False

        # _is_running :
        # - True if server is running, False is server is no more running
        # - Start : Set to true, try to start, if failed, set to False
        # - Stop : Set to False, stop server, stop client
        # - Means : During stop ongoing, will be False
        self._is_running = False

        # Gevent StreamServer
        self._server = None

        # Fork pids
        self._fork_pid_list = list()

        # Client management (re-entrant lock)
        self._client_connected_atomicint = AtomicIntSafe()
        self._client_connected_hash = dict()
        self._client_connected_hash_lock = RLock()

        # Lock for start/stop
        self.__stop_start_lock = Lock()

        # Control variables
        self._effective_control_interval_ms = 0

        # Control init
        self.__set_effective_controlinterval_ms()

        # Auto start
        if self._tcp_server_config.auto_start is True:
            logger.info("Auto-starting ON, starting now")
            self.start_server()
        else:
            logger.info("Auto-starting OFF")
Beispiel #19
0
    def main_helper(cls, argv, kwargs):
        """
        Main helper
        :param argv: Command line argv
        :type argv: list, tuple
        :param kwargs: Command line argv
        :type kwargs: dict
        :return Daemon
        :rtype Daemon
        """

        logger.debug("Entering, argv=%s, kwargs=%s", argv, kwargs)

        try:
            # Parse
            vars_hsh = cls.parse_arguments(argv)

            # Get stuff
            action = vars_hsh["action"]
            user = vars_hsh["user"]
            group = vars_hsh["group"]
            pidfile = vars_hsh["pidfile"]
            stdin = vars_hsh["stdin"]
            stdout = vars_hsh["stdout"]
            stderr = vars_hsh["stderr"]
            logfile = vars_hsh["logfile"]
            loglevel = vars_hsh["loglevel"]
            on_start_exit_zero = vars_hsh["onstartexitzero"]
            max_open_files = vars_hsh["maxopenfiles"]
            change_dir = vars_hsh["changedir"]
            timeout_ms = vars_hsh["timeoutms"]

            # New
            logconsole = vars_hsh["logconsole"]
            logsyslog = vars_hsh["logsyslog"]
            logsyslog_facility = vars_hsh["logsyslog_facility"]
            appname = vars_hsh["appname"]

            # Allocate now
            logger.debug("Allocating Daemon")
            di = cls.get_daemon_instance()

            # Store vars
            di.vars = vars_hsh

            logger.debug("Internal initialization, class=%s",
                         SolBase.get_classname(di))
            di._internal_init(
                pidfile=pidfile,
                stdin=stdin,
                stdout=stdout,
                stderr=stderr,
                logfile=logfile,
                loglevel=loglevel,
                on_start_exit_zero=on_start_exit_zero,
                max_open_files=max_open_files,
                change_dir=change_dir,
                timeout_ms=timeout_ms,
                logtosyslog=logsyslog,
                logtosyslog_facility=logsyslog_facility,
                logtoconsole=logconsole,
                app_name=appname,
            )

            logger.info("action=%s, user=%s, group=%s", action, user, group)

            if action == "start":
                di._daemon_start(user, group)
            elif action == "stop":
                di._daemon_stop()
            elif action == "status":
                di._daemon_status()
            elif action == "reload":
                di._daemon_reload()
            else:
                logger.info("Invalid action=%s", action)
                print(
                    "usage: %s -pidfile filename [_maxopenfiles int] [-timeoutms int] "
                    "[-stdin string] [-stdout string] [-stderr string] [-logfile string] [-loglevel string] [-changedir bool] "
                    "[-onstartexitzero bool] [-user string] [-group string] start|stop|status|reload"
                    % argv[0])
                sys.exit(2)

            # Done
            logger.debug("Done")
            return di
        except Exception as ex:
            logger.error("Exception, ex=%s", SolBase.extostr(ex))
            raise