Example #1
0
    def retrieve(self, itask):
        """Match external triggers for a waiting task proxy."""

        # Note this has to allow multiple same-message triggers to be queued
        # and only used one at a time.

        if self.queue.empty():
            return
        if len(itask.state.external_triggers) == 0:
            return
        bcast = BroadcastServer.get_inst()
        queued = []
        while True:
            try:
                queued.append(self.queue.get_nowait())
            except Empty:
                break
        used = []
        for trig, satisfied in itask.state.external_triggers.items():
            if satisfied:
                continue
            for qmsg, qid in queued:
                if trig == qmsg:
                    # Matched.
                    name, point_string = TaskID.split(itask.identity)
                    # Set trigger satisfied.
                    itask.state.external_triggers[trig] = True
                    cylc.flags.pflag = True
                    # Broadcast the event ID to the cycle point.
                    if qid is not None:
                        bcast.put(
                            [point_string],
                            ["root"],
                            [{
                                'environment': {
                                    'CYLC_EXT_TRIGGER_ID': qid
                                }
                            }]
                        )
                    used.append((qmsg, qid))
                    break
        for q in queued:
            if q not in used:
                self.queue.put(q)
Example #2
0
    def retrieve(self, itask):
        """Match external triggers for a waiting task proxy."""

        # Note this has to allow multiple same-message triggers to be queued
        # and only used one at a time.

        if self.queue.empty():
            return
        if len(itask.state.external_triggers) == 0:
            return
        bcast = BroadcastServer.get_inst()
        queued = []
        while True:
            try:
                queued.append(self.queue.get_nowait())
            except Empty:
                break
        used = []
        for trig, satisfied in itask.state.external_triggers.items():
            if satisfied:
                continue
            for qmsg, qid in queued:
                if trig == qmsg:
                    # Matched.
                    name, point_string = TaskID.split(itask.identity)
                    # Set trigger satisfied.
                    itask.state.external_triggers[trig] = True
                    cylc.flags.pflag = True
                    # Broadcast the event ID to the cycle point.
                    if qid is not None:
                        bcast.put([point_string], ["root"], [{
                            'environment': {
                                'CYLC_EXT_TRIGGER_ID': qid
                            }
                        }])
                    used.append((qmsg, qid))
                    break
        for q in queued:
            if q not in used:
                self.queue.put(q)
Example #3
0
    def dump(self, tasks=None):
        """Dump suite states to disk. Return state file basename on success."""

        wireless = BroadcastServer.get_inst()

        base_name = self.BASE_NAME + "." + get_current_time_string(
            override_use_utc=True, use_basic_format=True,
            display_sub_seconds=True
        )
        file_name = os.path.join(self.dir_name, base_name)

        # write the state dump file, retrying several times in case of:
        # (a) log rolling error when cylc-run contents have been deleted,
        # (b) "[Errno 9] bad file descriptor" at BoM - see github #926.
        max_attempts = 5
        n_attempt = 1
        while True:
            handle = None
            try:
                handle = open(file_name, "wb")

                handle.write('run mode : %s\n' % self.run_mode)
                handle.write('time : %s (%d)\n' % (
                    get_current_time_string(), time.time()))

                handle.write(self.cts_str)
                wireless.dump(handle)
                handle.write('Begin task states\n')

                if tasks is None and self.pool is not None:
                    tasks = self.pool.get_all_tasks()
                if tasks is not None:
                    for itask in sorted(tasks, key=lambda t: t.identity):
                        handle.write("%s : status=%s, spawned=%s\n" % (
                            itask.identity, itask.state.status,
                            itask.has_spawned))

                # To generate "OSError [Errno 9] bad file descriptor",
                # close the file with os.close() before calling fsync():
                # # os.close( handle.fileno() )

                os.fsync(handle.fileno())
                handle.close()
            except (IOError, OSError) as exc:
                # No such file or directory? It is likely that the directory
                # has been removed and is not recoverable.
                if exc.errno == errno.ENOENT:
                    raise
                if not exc.filename:
                    exc.filename = file_name
                self.log.warning(
                    'State dumping failed, #%d %s' % (n_attempt, exc))
                if n_attempt >= max_attempts:
                    raise exc
                n_attempt += 1
                if handle is not None:
                    try:
                        handle.close()
                    except (IOError, OSError) as exc:
                        self.log.warning(
                            'State file handle closing failed: %s' % exc)
                time.sleep(0.2)
            else:
                break

        # Point "state" symbolic link to new dated state dump
        try:
            os.unlink(self.file_name)
        except OSError as exc:
            if exc.errno != errno.ENOENT:
                raise
        os.symlink(base_name, self.file_name)
        self.arch_files.append(file_name)
        # Remove state dump older than archive length
        while len(self.arch_files) > self.arch_len:
            try:
                os.unlink(self.arch_files.pop(0))
            except OSError as exc:
                if exc.errno != errno.ENOENT:
                    raise
        return base_name
Example #4
0
    def dump(self, tasks=None):
        """Dump suite states to disk. Return state file basename on success."""

        wireless = BroadcastServer.get_inst()

        base_name = self.BASE_NAME + "." + get_current_time_string(
            override_use_utc=True,
            use_basic_format=True,
            display_sub_seconds=True)
        file_name = os.path.join(self.dir_name, base_name)

        # write the state dump file, retrying several times in case of:
        # (a) log rolling error when cylc-run contents have been deleted,
        # (b) "[Errno 9] bad file descriptor" at BoM - see github #926.
        max_attempts = 5
        n_attempt = 1
        while True:
            handle = None
            try:
                handle = open(file_name, "wb")

                handle.write('run mode : %s\n' % self.run_mode)
                handle.write('time : %s (%d)\n' %
                             (get_current_time_string(), time.time()))

                handle.write(self.cts_str)
                wireless.dump(handle)
                handle.write('Begin task states\n')

                if tasks is None and self.pool is not None:
                    tasks = self.pool.get_all_tasks()
                if tasks is not None:
                    for itask in sorted(tasks, key=lambda t: t.identity):
                        itask.dump_state(handle)

                # To generate "OSError [Errno 9] bad file descriptor",
                # close the file with os.close() before calling fsync():
                # # os.close( handle.fileno() )

                os.fsync(handle.fileno())
                handle.close()
            except (IOError, OSError) as exc:
                # No such file or directory? It is likely that the directory
                # has been removed and is not recoverable.
                if exc.errno == errno.ENOENT:
                    raise
                if not exc.filename:
                    exc.filename = file_name
                self.log.warning('State dumping failed, #%d %s' %
                                 (n_attempt, exc))
                if n_attempt >= max_attempts:
                    raise exc
                n_attempt += 1
                if handle is not None:
                    try:
                        handle.close()
                    except (IOError, OSError) as exc:
                        self.log.warning(
                            'State file handle closing failed: %s' % exc)
                time.sleep(0.2)
            else:
                break

        # Point "state" symbolic link to new dated state dump
        try:
            os.unlink(self.file_name)
        except OSError as exc:
            if exc.errno != errno.ENOENT:
                raise
        os.symlink(base_name, self.file_name)
        self.arch_files.append(file_name)
        # Remove state dump older than archive length
        while len(self.arch_files) > self.arch_len:
            try:
                os.unlink(self.arch_files.pop(0))
            except OSError as exc:
                if exc.errno != errno.ENOENT:
                    raise
        return base_name