Exemple #1
0
 def test_without_expires(_batch):
     batch = _batch.get_batch.return_value
     assert _cache.global_set(b"key", b"value") is batch.add.return_value
     _batch.get_batch.assert_called_once_with(
         _cache._GlobalCacheSetBatch, {}
     )
     batch.add.assert_called_once_with(b"key", b"value")
Exemple #2
0
 def test_with_expires(_batch):
     batch = _batch.get_batch.return_value
     future = _cache.global_set(b"key", b"value", expires=5)
     assert future is batch.add.return_value
     _batch.get_batch.assert_called_once_with(_cache._GlobalCacheSetBatch,
                                              {"expires": 5})
     batch.add.assert_called_once_with(b"key", b"value")
Exemple #3
0
def put(entity, options):
    """Store an entity in datastore.

    The entity can be a new entity to be saved for the first time or an
    existing entity that has been updated.

    Args:
        entity_pb (datastore.Entity): The entity to be stored.
        options (_options.Options): Options for this request.

    Returns:
        tasklets.Future: Result will be completed datastore key
            (datastore.Key) for the entity.
    """
    context = context_module.get_context()
    use_global_cache = context._use_global_cache(entity.key, options)
    use_datastore = context._use_datastore(entity.key, options)
    if not (use_global_cache or use_datastore):
        raise TypeError("use_global_cache and use_datastore can't both be False")

    if not use_datastore and entity.key.is_partial:
        raise TypeError("Can't store partial keys when use_datastore is False")

    lock = None
    entity_pb = helpers.entity_to_protobuf(entity)
    cache_key = _cache.global_cache_key(entity.key)
    if use_global_cache and not entity.key.is_partial:
        if use_datastore:
            lock = yield _cache.global_lock_for_write(cache_key)
        else:
            expires = context._global_cache_timeout(entity.key, options)
            cache_value = entity_pb.SerializeToString()
            yield _cache.global_set(cache_key, cache_value, expires=expires)

    if use_datastore:
        transaction = context.transaction
        if transaction:
            batch = _get_commit_batch(transaction, options)
        else:
            batch = _batch.get_batch(_NonTransactionalCommitBatch, options)

        key_pb = yield batch.put(entity_pb)
        if key_pb:
            key = helpers.key_from_protobuf(key_pb)
        else:
            key = None

        if lock:
            if transaction:

                def callback():
                    _cache.global_unlock_for_write(cache_key, lock).result()

                context.call_on_transaction_complete(callback)

            else:
                yield _cache.global_unlock_for_write(cache_key, lock)

        raise tasklets.Return(key)
Exemple #4
0
    def test_error_strict(_batch, _global_cache, sleep):
        class TransientError(Exception):
            pass

        sleep.return_value = future_result(None)
        batch = _batch.get_batch.return_value
        future = _future_exception(TransientError("oops"))
        batch.add.return_value = future
        _global_cache.return_value = mock.Mock(
            transient_errors=(TransientError,),
            spec=("transient_errors", "strict_write"),
        )

        with pytest.raises(TransientError):
            _cache.global_set(b"key", b"value").result()

        _batch.get_batch.assert_called_with(_cache._GlobalCacheSetBatch, {})
        batch.add.assert_called_with(b"key", b"value")
Exemple #5
0
    def test_error_strict(_batch, _global_cache):
        class TransientError(Exception):
            pass

        batch = _batch.get_batch.return_value
        future = _future_exception(TransientError("oops"))
        batch.add.return_value = future
        _global_cache.return_value = mock.Mock(
            transient_errors=(TransientError, ),
            clear_cache_soon=False,
            spec=("transient_errors", "clear_cache_soon", "strict_write"),
        )

        with pytest.raises(TransientError):
            _cache.global_set(b"key", b"value").result()

        _batch.get_batch.assert_called_once_with(_cache._GlobalCacheSetBatch,
                                                 {})
        batch.add.assert_called_once_with(b"key", b"value")
        assert _global_cache.return_value.clear_cache_soon is True
Exemple #6
0
    def test_without_expires(_batch, _global_cache):
        batch = _batch.get_batch.return_value
        future = _future_result("hi mom!")
        batch.add.return_value = future
        _global_cache.return_value = mock.Mock(
            transient_errors=(),
            strict_write=False,
            spec=("transient_errors", "strict_write"),
        )

        assert _cache.global_set(b"key", b"value").result() == "hi mom!"
        _batch.get_batch.assert_called_once_with(_cache._GlobalCacheSetBatch, {})
        batch.add.assert_called_once_with(b"key", b"value")
Exemple #7
0
    def test_with_expires(_batch, _global_cache):
        batch = _batch.get_batch.return_value
        future = _future_result("hi mom!")
        batch.add.return_value = future
        _global_cache.return_value = mock.Mock(
            transient_errors=(),
            clear_cache_soon=False,
            spec=("transient_errors", "clear_cache_soon"),
        )

        future = _cache.global_set(b"key", b"value", expires=5)
        assert future.result() == "hi mom!"
        _batch.get_batch.assert_called_once_with(_cache._GlobalCacheSetBatch,
                                                 {"expires": 5})
        batch.add.assert_called_once_with(b"key", b"value")
Exemple #8
0
    def test_error_not_strict_already_warned(_batch, _global_cache):
        class TransientError(Exception):
            pass

        batch = _batch.get_batch.return_value
        error = TransientError("oops")
        error._ndb_warning_logged = True
        future = _future_exception(error)
        batch.add.return_value = future
        _global_cache.return_value = mock.Mock(
            transient_errors=(TransientError,),
            strict_write=False,
            spec=("transient_errors", "strict_write"),
        )

        with warnings.catch_warnings(record=True) as logged:
            assert _cache.global_set(b"key", b"value").result() is None
            assert len(logged) == 0

        _batch.get_batch.assert_called_once_with(_cache._GlobalCacheSetBatch, {})
        batch.add.assert_called_once_with(b"key", b"value")