Example #1
0
def main(argv=sys.argv):
    if len(argv) < 2:
        usage(argv)
    config_uri = argv[1]
    options = parse_vars(argv[2:])
    setup_logging(config_uri)
    settings = get_appsettings(config_uri, options=options)

    from gengine.base.settings import set_settings
    set_settings(settings)

    durl = os.environ.get("DATABASE_URL")  # heroku
    if durl:
        settings['sqlalchemy.url'] = durl

    murl = os.environ.get("MEMCACHED_URL")
    if murl:
        settings['urlcache_url'] = murl

    engine = engine_from_config(settings, 'sqlalchemy.')

    config = Configurator(settings=settings)
    pyramid_dogpile_cache.includeme(config)

    from gengine.metadata import (
        init_session,
        init_declarative_base,
        init_db
    )
    init_session()
    init_declarative_base()
    init_db(engine)
    init_caches()

    from gengine.metadata import (
        DBSession
    )
    sess = DBSession()
    init_session(override_session=sess, replace=True)

    import gengine.app.model as m
    with transaction.manager:
        mark_changed(sess, transaction.manager, True)

        messages = sess.execute(m.t_user_messages.select().where(m.t_user_messages.c.has_been_pushed == False))
        for msg in messages:
            m.UserMessage.deliver(msg)
        sess.flush()
        sess.commit()
def main(argv=sys.argv):
    if len(argv) < 2:
        usage(argv)
    config_uri = argv[1]
    options = parse_vars(argv[2:])
    setup_logging(config_uri)
    settings = get_appsettings(config_uri, options=options)

    import gengine
    gengine.main({}, **settings)

    from gengine.metadata import (DBSession)
    sess = DBSession()

    import gengine.app.model as m
    import crontab

    from gengine.app.registries import get_task_registry
    enginetasks = get_task_registry().registrations

    with transaction.manager:
        mark_changed(sess, transaction.manager, True)

        tasks = sess.execute(m.t_tasks.select()).fetchall()

        for task in tasks:
            cron = task["cron"]
            if not cron:
                cron = enginetasks.get(task["task_name"]).get(
                    "default_cron", None)

            if cron:

                now = dt_now().replace(second=0)

                item = crontab.CronItem(line=cron)
                s = item.schedule(date_from=now)
                prev = s.get_next().replace(second=0)
                next = s.get_next().replace(second=0)

                execs = sess.execute(m.t_taskexecutions.select().where(
                    and_(
                        m.t_taskexecutions.c.task_id == task["id"],
                        m.t_taskexecutions.c.canceled_at == None,
                        m.t_taskexecutions.c.finished_at == None,
                    )).order_by(
                        m.t_taskexecutions.c.planned_at.desc())).fetchall()

                found = False

                for exec in execs:

                    if exec["planned_at"] >= next:
                        # The next execution is already planned
                        found = True

                    if exec["planned_at"] <= prev and prev < dt_ago(
                            minutes=10) and not exec["locked_at"]:
                        #  The execution is more than 10 minutes in the past and not yet locked (worker not running / overloaded)
                        if next - datetime.timedelta(minutes=10) < dt_now():
                            # The next execution is planned in less than 10 minutes, cancel the other one
                            sess.execute(m.t_taskexecutions.update().values({
                                'canceled_at':
                                dt_now()
                            }).where({'id': exec["id"]}))

                    if exec["locked_at"] and exec["locked_at"] < dt_ago(
                            hours=24):
                        # this task is running for more than 24 hours. probably crashed.... set it to canceled
                        sess.execute(m.t_taskexecutions.update().values({
                            'canceled_at':
                            dt_now()
                        }).where({'id': exec["id"]}))

                if not found:
                    # Plan next execution
                    sess.execute(m.t_taskexecutions.insert().values({
                        'task_id':
                        task["id"],
                        'planned_at':
                        next
                    }))

        sess.flush()
        sess.commit()