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))
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))
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
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
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
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
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
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
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
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
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
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)
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)
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
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)
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)
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")
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