Skip to content

Commit

Permalink
docs: explain singletons using LRU cache #299
Browse files Browse the repository at this point in the history
  • Loading branch information
proofit404 committed May 25, 2022
1 parent 5259785 commit 532a5b0
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 1 deletion.
57 changes: 57 additions & 0 deletions docs/value.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,61 @@ be injected in corresponding argument of `Foo` and `Bar` constructors.
As you can see `@value` decorated function was called only once even two objects
depends on it.

## Singletons

The singleton pattern is considered a bad practice in general. But in some cases
you would actually need to use them. For example, if you instantiate connection
pool for you database, message queue, or cache.

In that case you could use `functools.lru_cache` together with `@value`
decorator.

Let assume you would like to instantiate your view class each time you need to
handle a separate HTTP request. If your view class would depend on connection
pool, it would not be recreated each time you want to process the request.

Nice thing about this approach - you don't need to make connection pool a
singleton itself. This logic would kept inside `Injector` subclass, which would
make pool class a little bit more testable.

```pycon

>>> from functools import lru_cache

>>> class Connections:
... """Connection pool."""
... def __init__(self, host, port):
... ...
...
... def connect(self):
... ...

>>> class Request:
... def __init__(self, connections):
... self.connections = connections

>>> class Container(Injector):
... request = Request
... host = "localhost"
... port = 1234
...
... @value
... @lru_cache
... def connections(host, port):
... pool = Connections(host, port)
... pool.connect()
... return port

>>> request1 = Container.request

>>> request2 = Container.request

>>> request1 is request2
False

>>> request1.connections is request2.connections
True

```

<p align="center">&mdash;&mdash;</p>
2 changes: 1 addition & 1 deletion tests/test_objects_value.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ class Container(Injector):
foo = Foo

@value
@lru_cache()
@lru_cache() # noqa: B019
def bar():
return randint(0, 1000)

Expand Down

0 comments on commit 532a5b0

Please sign in to comment.