Skip to content

Commit

Permalink
fix(inventory): always use fresh cache on new cached session (#404)
Browse files Browse the repository at this point in the history
##### SUMMARY

The class scoped `cache` dict was being shared across all
`cached_session`, we now make sure that the cache is instance scoped.

Fixes #403

##### ISSUE TYPE

- Bugfix Pull Request
  • Loading branch information
jooola authored Nov 24, 2023
1 parent 04f63d0 commit df7fa04
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 4 deletions.
1 change: 1 addition & 0 deletions .ansible-lint
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ exclude_paths:
- .git/
- .github/
- changelogs/
- examples/
- tests/integration/targets/certificate
- tests/integration/targets/firewall
- tests/integration/targets/floating_ip
Expand Down
2 changes: 2 additions & 0 deletions changelogs/fragments/fix-inventory-fresh-cache.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
bugfixes:
- hcloud inventory - Ensure the API client use a new cache for every *cached session*.
35 changes: 35 additions & 0 deletions examples/use-refresh-inventory.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
- name: Demonstrate the usage of 'refresh_inventory'
hosts: localhost
connection: local

tasks:
- name: Print hostvars
ansible.builtin.debug:
var: hostvars

- name: Create new server
hetzner.hcloud.server:
name: my-server
server_type: cx11
image: debian-12

- name: Refresh inventory
ansible.builtin.meta: refresh_inventory

- name: Run tests
block:
- name: Print updated inventory
ansible.builtin.debug:
var: hostvars

- name: Verify hostvars is not empty
ansible.builtin.assert:
that:
- hostvars != {}

always:
- name: Cleanup server
hetzner.hcloud.server:
name: my-server
state: absent
14 changes: 10 additions & 4 deletions plugins/module_utils/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,11 @@ def client_get_by_name_or_id(client: Client, resource: str, param: str | int):
if HAS_REQUESTS:

class CachedSession(requests.Session):
cache: dict[str, requests.Response] = {}
cache: dict[str, requests.Response]

def __init__(self) -> None:
super().__init__()
self.cache = {}

def send(self, request: requests.PreparedRequest, **kwargs) -> requests.Response: # type: ignore[no-untyped-def]
"""
Expand All @@ -89,7 +93,7 @@ def send(self, request: requests.PreparedRequest, **kwargs) -> requests.Response

class Client(ClientBase):
@contextmanager
def cached_session(self) -> None:
def cached_session(self):
"""
Swap the client session during the scope of the context. The session will cache
all GET requests.
Expand All @@ -98,5 +102,7 @@ def cached_session(self) -> None:
for long living scopes.
"""
self._requests_session = CachedSession()
yield
self._requests_session = requests.Session()
try:
yield
finally:
self._requests_session = requests.Session()

0 comments on commit df7fa04

Please sign in to comment.