Esempio n. 1
0
def export_task(req: "CamcopsRequest", recipient: ExportRecipient,
                task: Task) -> None:
    """
    Exports a single task, checking that it remains valid to do so.
    
    Args:
        req: a :class:`camcops_server.cc_modules.cc_request.CamcopsRequest`
        recipient: an :class:`camcops_server.cc_modules.cc_exportmodels.ExportRecipient`
        task: a :class:`camcops_server.cc_modules.cc_task.Task` 
    """  # noqa

    # Double-check it's OK! Just in case, for example, an old backend task has
    # persisted, or someone's managed to get an iffy back-end request in some
    # other way.
    if not recipient.is_task_suitable(task):
        # Warning will already have been emitted.
        return

    cfg = req.config
    lockfilename = cfg.get_export_lockfilename_task(
        recipient_name=recipient.recipient_name,
        basetable=task.tablename,
        pk=task.get_pk(),
    )
    dbsession = req.dbsession
    try:
        with lockfile.FileLock(lockfilename, timeout=0):  # doesn't wait
            # We recheck the export status once we hold the lock, in case
            # multiple jobs are competing to export it.
            if ExportedTask.task_already_exported(
                    dbsession=dbsession,
                    recipient_name=recipient.recipient_name,
                    basetable=task.tablename,
                    task_pk=task.get_pk()):
                log.info(
                    "Task {!r} already exported to recipient {!r}; "
                    "ignoring", task, recipient)
                # Not a warning; it's normal to see these because it allows the
                # client API to skip some checks for speed.
                return
            # OK; safe to export now.
            et = ExportedTask(recipient, task)
            dbsession.add(et)
            et.export(req)
            dbsession.commit()  # so the ExportedTask is visible to others ASAP
    except lockfile.AlreadyLocked:
        log.warning(
            "Export logfile {!r} already locked by another process; "
            "aborting", lockfilename)
Esempio n. 2
0
    def make_from_task(cls, task: Task,
                       indexed_at_utc: Pendulum) -> "TaskIndexEntry":
        """
        Returns a task index entry for the specified
        :class:`camcops_server.cc_modules.cc_task.Task`. The
        returned index requires inserting into a database session.

        Args:
            task:
                a :class:`camcops_server.cc_modules.cc_task.Task`
            indexed_at_utc:
                current time in UTC
        """
        assert indexed_at_utc is not None, "Missing indexed_at_utc"

        index = cls()

        index.indexed_at_utc = indexed_at_utc

        index.task_table_name = task.tablename
        index.task_pk = task.get_pk()

        patient = task.patient
        index.patient_pk = patient.get_pk() if patient else None

        index.device_id = task.get_device_id()
        index.era = task.get_era()
        index.when_created_utc = task.get_creation_datetime_utc()
        index.when_created_iso = task.when_created
        # noinspection PyProtectedMember
        index.when_added_batch_utc = task._when_added_batch_utc
        index.adding_user_id = task.get_adding_user_id()
        index.group_id = task.get_group_id()
        index.task_is_complete = task.is_complete()

        return index