Beispiel #1
0
 def testing(klass: Type['ConfigContext'],
             context: VerediContext) -> Nullable[bool]:
     '''
     Returns the unit-testing link field or Null.
     '''
     unit_testing = context._sub_get(klass.KEY, ConfigLink.UNIT_TESTING)
     return unit_testing or Null()
Beispiel #2
0
 def subproc(klass: Type['ConfigContext'],
             context: VerediContext) -> Nullable['SubToProcComm']:
     '''
     Returns a SubToProcComm or Null.
     '''
     comms = context._sub_get(klass.KEY, ConfigLink.SUB_PROC)
     return comms or Null()
Beispiel #3
0
 def log_level(klass: Type['ConfigContext'],
               context: VerediContext) -> log.Level:
     '''
     Returns log_level in `context` or Null.
     '''
     return log.Level.to_logging(
         context._sub_get(klass.KEY, ConfigLink.LOG_LEVEL))
Beispiel #4
0
 def keychain(klass: Type['ConfigContext'],
              context: VerediContext) -> Nullable[Iterable[Any]]:
     '''
     Checks for a KEYCHAIN link in config's spot in this context.
     '''
     keychain = context.sub_get(ConfigLink.KEYCHAIN)
     return keychain
Beispiel #5
0
 def source_id(klass: Type['InputContext'],
               context: VerediContext) -> Union[int, 'MonotonicId']:
     '''
     If there is a source id (EntityId, whatever), get it.
     '''
     input_ctx = context._get().get(klass.KEY, {})
     ident = input_ctx.get(InputLink.SOURCE_ID, None)
     return ident
Beispiel #6
0
 def source_designation(klass: Type['InputContext'],
                        context: VerediContext) -> Optional[str]:
     '''
     Checks for & returns our Input ID or InputId.INVALID.
     '''
     input_ctx = context._get().get(klass.KEY, {})
     designation = input_ctx.get(InputLink.SOURCE_DESIGNATION, None)
     return designation
Beispiel #7
0
 def input_id(klass: Type['InputContext'],
              context: VerediContext) -> Optional[InputId]:
     '''
     Checks for & returns our Input ID or InputId.INVALID.
     '''
     input_ctx = context._get().get(klass.KEY, {})
     input_id = input_ctx.get(InputLink.INPUT_ID, InputId.INVALID)
     return input_id
Beispiel #8
0
 def log_is_server(klass: Type['ConfigContext'],
                   context: VerediContext) -> bool:
     '''
     Returns True if the process is a log_server.
     '''
     # _sub_get() returns None if key not found, which is convenient for
     # converting to a bool.
     return bool(context._sub_get(klass.KEY, ConfigLink.LOG_SERVER))
Beispiel #9
0
 def type(klass: Type['InputContext'],
          context: VerediContext) -> Union[int, enum.Enum]:
     '''
     If there is a type id, get it.
     '''
     input_ctx = context._get().get(klass.KEY, {})
     type_id = input_ctx.get(InputLink.TYPE, None)
     return type_id
Beispiel #10
0
 def input(klass: Type['InputContext'],
           context: VerediContext) -> Optional[str]:
     '''
     Checks for & returns our input string or None.
     '''
     input_ctx = context._get().get(klass.KEY, {})
     input_id = input_ctx.get(InputLink.INPUT_SAFE, None)
     return input_id
Beispiel #11
0
    def id(klass: Type['ConfigContext'],
           context: VerediContext) -> Nullable[Any]:
        '''
        Checks for an ID link in config's spot in this context.

        If none, returns Null().
        '''
        id = context.sub_get(ConfigLink.ID)
        if not id:
            log.debug("No id in context! context.id: {}, ",
                      id,
                      context=context)
        return id
Beispiel #12
0
    def path(klass: Type['ConfigContext'],
             context: VerediContext) -> Nullable[pathlib.Path]:
        '''
        Checks for a PATH link in config's spot in this context.

        If none, returns PATH from background.manager.data.
        '''
        path = context.sub_get(ConfigLink.PATH)
        if null_or_none(path):
            log.debug(
                "No path in context; using background's. "
                "context.path: {}, ",
                "bg.path: {}",
                path,
                background.manager.data.path,
                context=context)
            path = background.manager.data.path
        return path
Beispiel #13
0
 def set_testing(klass: Type['ConfigContext'], context: VerediContext,
                 value: 'SubToProcComm') -> None:
     '''
     Sets the unit-testing link field. Pops if `value` is None.
     '''
     context._sub_set(klass.KEY, ConfigLink.UNIT_TESTING, value)
Beispiel #14
0
 def set_log_is_server(klass: Type['ConfigContext'], context: VerediContext,
                       is_server: bool) -> None:
     '''
     Set is_server in `context`. Pops if `is_server` is None.
     '''
     context._sub_set(klass.KEY, ConfigLink.LOG_SERVER, is_server)
Beispiel #15
0
 def set_log_level(klass: Type['ConfigContext'], context: VerediContext,
                   level: log.LogLvlConversion) -> None:
     '''
     Sets log_level in `context`. Pops if `level` is None.
     '''
     context._sub_set(klass.KEY, ConfigLink.LOG_LEVEL, level)
Beispiel #16
0
 def set_subproc(klass: Type['ConfigContext'], context: VerediContext,
                 value: 'SubToProcComm') -> None:
     '''
     Sets a SubToProcComm. Pops if `value` is None.
     '''
     context._sub_set(klass.KEY, ConfigLink.SUB_PROC, value)
Beispiel #17
0
def set_up(
    proc_name: str,
    config: Configuration,
    context: VerediContext,
    entry_fn: StartProcFn,
    t_proc_to_sub: Type['ProcToSubComm'] = ProcToSubComm,
    t_sub_to_proc: Type['SubToProcComm'] = SubToProcComm,
    finalize_fn: FinalizeInitFn = None,
    initial_log_level: Optional[log.Level] = None,
    debug_flags: Optional[DebugFlag] = None,
    unit_testing: Optional[bool] = False,
    proc_test: Optional[ProcTest] = None,
    shutdown: Optional[multiprocessing.Event] = None
) -> Optional[ProcToSubComm]:
    '''
    Get a process ready for _run_proc().

    If `t_proc_to_sub` and/or `t_sub_to_proc` are not default, those classes
    will be instantiated instead of ProcToSubComm / SubToProcComm.

    If `unit_testing`, creates the ut_pipe side-channel.

    If `finalize_fn`, sends both ProcToSubComm and SubToProcComm objects in to
    be processed just before set-up is complete.

    `shutdown` is an optional param in case caller wants multiple sub-processes
    to share the same shutdown flag.

    Returns a `t_proc_to_sub` (default: ProcToSubComm) object. When ready to
    start/run the subprocess, call start() on it.
    '''
    logger = log.get_logger(proc_name, min_log_level=initial_log_level)
    log_dotted = label.normalize(_DOTTED_FUNCS, 'set_up')

    if proc_test and proc_test.has(ProcTest.DNE):
        # This process 'Does Not Exist' right now.
        # Should we downgrade this to debug, or error out more heavily?
        # (i.e. exception?)
        log.group_multi(_LOG_INIT,
                        log_dotted,
                        "'{}' has {}. Skipping creation.",
                        proc_name,
                        proc_test,
                        veredi_logger=logger,
                        log_minimum=log.Level.ERROR,
                        log_success=False)
        return None

    # ------------------------------
    # Create multiproc IPC stuff.
    # ------------------------------
    log.group_multi(_LOG_INIT,
                    log_dotted,
                    "'{}': Creating inter-process communication...",
                    proc_name,
                    veredi_logger=logger)

    # The official us<->them IPC pipe.
    child_pipe, parent_pipe = multiprocessing.Pipe()

    # The side-channel/unit-test us<->them IPC pipe.
    ut_child_pipe, ut_parent_pipe = None, None
    if unit_testing:
        log.group_multi(_LOG_INIT,
                        log_dotted, "'{}': Creating unit-testing "
                        "inter-process communication...",
                        proc_name,
                        veredi_logger=logger)
        ut_child_pipe, ut_parent_pipe = multiprocessing.Pipe()
        context.add('proc-test', proc_test)

    # multiproc shutdown flag
    if not shutdown:
        log.group_multi(_LOG_INIT,
                        log_dotted, "'{}': Creating shutdown inter-process "
                        "event flag...",
                        proc_name,
                        veredi_logger=logger)
        shutdown = multiprocessing.Event()

    # ------------------------------
    # Create the process's private info.
    # ------------------------------
    log.group_multi(_LOG_INIT,
                    log_dotted,
                    "'{}': Creating process comms objects...",
                    proc_name,
                    veredi_logger=logger)

    # Info for the proc itself to own.
    comms = t_sub_to_proc(name=proc_name,
                          config=config,
                          entry_fn=entry_fn,
                          pipe=child_pipe,
                          shutdown=shutdown,
                          debug_flags=debug_flags,
                          ut_pipe=ut_child_pipe)

    # ---
    # Updated Context w/ start-up info (SubToProcComm, etc).
    # ---
    log.group_multi(_LOG_INIT,
                    log_dotted,
                    "'{}': Saving into the ConfigContext...",
                    proc_name,
                    veredi_logger=logger)
    ConfigContext.set_log_level(context, initial_log_level)
    ConfigContext.set_subproc(context, comms)

    # ------------------------------
    # Create the Process, ProcToSubComm
    # ------------------------------
    subp_args = [context]
    subp_kwargs = {}

    log.group_multi(_LOG_INIT,
                    log_dotted,
                    "'{}': Creating the sub-process object...",
                    proc_name,
                    veredi_logger=logger)

    # Create the process object (doesn't start the process).
    subprocess = multiprocessing.Process(
        # _subproc_entry() is always the target; it will do some setup and then
        # call the actual target: `entry_fn`.
        target=_subproc_entry,
        name=proc_name,
        args=subp_args,
        kwargs=subp_kwargs)

    # Info for the caller about the proc and how to talk to.
    proc = t_proc_to_sub(name=proc_name,
                         process=subprocess,
                         pipe=parent_pipe,
                         shutdown=shutdown,
                         ut_pipe=ut_parent_pipe)

    # ------------------------------
    # Use Finalize Callback, if supplied.
    # ------------------------------
    if finalize_fn:
        log.group_multi(_LOG_INIT,
                        log_dotted, "'{}': Finalize function supplied. "
                        "Calling {}...",
                        proc_name,
                        finalize_fn,
                        veredi_logger=logger)
        finalize_fn(proc, comms)

    # ------------------------------
    # Return ProcToSubComm for caller to use to communicate to sub-proc.
    # ------------------------------
    log.group_multi(_LOG_INIT,
                    log_dotted,
                    "'{}': Set-up complete.",
                    proc_name,
                    veredi_logger=logger)
    return proc