Example #1
0
def enqueue_post_task(shard, post_ids, new_topic=None):
    """Enqueues a task to post a new task on a shard."""
    params_dict = dict(shard=shard, post_ids=post_ids)
    if new_topic is not None:
        params_dict.update(new_topic=new_topic)

    taskqueue.Task(
        method='PULL',
        tag=str(shard),
        params=params_dict,
    ).add(config.pending_queue, transactional=ndb.in_transaction())
Example #2
0
def update_read_state(topic_dict, user_id):
    """Updates a user's read state for a given set of topics.

    Will inherit transaction state on user_id's LoginRecord if this is
    called from within an existing transition.

    Args:
        topic_dict: Maps topic shard IDs to the new sequence number to assign
            for that shard.
        user_id: User ID that is being updated.
    """
    # TODO(bslatkin): Consider validating the topic list provided here
    # to ensure they are actually associated with the current logged-in shard.
    # The possible damage here is restricted to the user so we don't care much.
    read_state_keys = [
        ndb.Key(models.LoginRecord._get_kind(), user_id,
                models.ReadState._get_kind(), topic)
        for topic in topic_dict]

    def txn():
        read_state_list = ndb.get_multi(read_state_keys)
        to_put = []
        for key, read_state in zip(read_state_keys, read_state_list):
            next_read_sequence = topic_dict[key.id()]
            if read_state is None:
                read_state = models.ReadState(key=key)
                read_state.last_read_sequence = next_read_sequence
            else:
                read_state.last_read_sequence = max(
                    read_state.last_read_sequence, next_read_sequence)

            to_put.append(read_state)

        ndb.put_multi(to_put)

    if ndb.in_transaction():
        txn()
    else:
        ndb.transaction(txn)