Skip to content

Re-use existing scrape sessions after scrape timeout - #25

Open
EatonEmmerich wants to merge 15 commits into
masterfrom
NGC-2100
Open

EatonEmmerich wants to merge 15 commits into
masterfrom
NGC-2100

Conversation

@EatonEmmerich

Copy link
Copy Markdown
Contributor

The cache now creates a "scraper" rather than a "switch"
The scraper keeps state regarding the success of the last collection, and if it hasn't been reported yet, report that instead without starting a new scrape.

if now - self.lldp_time < self.lldp_timeout:
return
await self._update_lldp()
self.lldp_time = now

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like a bug we left from the previous iteration.

@EatonEmmerich EatonEmmerich changed the title Reuse existing scrape sessions after scrape timeout Re-use existing scrape sessions after scrape timeout Sep 4, 2026
@EatonEmmerich
EatonEmmerich marked this pull request as ready for review September 4, 2026 12:08

@amishatishpatel amishatishpatel left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor comments/suggestions. Thanks for running me through the expected behaviour.

Comment thread src/switch_exporter/server.py Outdated
return web.Response(text=content)


def scraper_factory(switch_factory) -> Callable[[Cache, str], Scraper]:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reckon switch_factory needs a type hint itself.

registry=registry,
)

# TODO: Use a TaskGroup instead of a list of tasks to robustly handle the async context.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reckon this TODO is still valuable, but I'm not sure it's possible with your current approach of Scraper.wait_for_scraper.

@EatonEmmerich EatonEmmerich Sep 9, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the reason this todo is still there is that this will require bumping python version from 3.6 to 3.10+

Comment thread src/switch_exporter/switch.py Outdated
raise TypeError(f'Expected str, got {type(result)}')
return result

async def maybe_refresh_port_info(self) -> None:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally, big fan of this method name, but I reckon it needs to be less mysterious/ambiguous for anyone new to this (including me).

  • I reckon just calling it refresh_port_info should be fine
  • If you really want to indicate conditions for updating, that should go in the docstring(s) of the constituent _populate_ports() and _update_lldp()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reason: If I see a method called maybe_do_something() with no args in the call, I immediately think it's like a random throw of dice 😆

Comment thread src/switch_exporter/scraper.py Outdated
Comment on lines +72 to +79
if not self.done.is_set():
await self.wait_for_scraper()
return self.registry

self.done.clear()
self.timeout = timeout # set timeout dynamically for scrape from params
self.exceptions.clear()
self.registry = prometheus_client.CollectorRegistry()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'm with you here Re: "Guarding against concurrent scrape requests" (right?)

  • TIL a new asyncio.Event.is_set() returns False
  • I'd still prefer self.registry be declared before that check on Line 72

Comment thread src/switch_exporter/switch.py Outdated
Comment on lines +120 to +123
async def maybe_refresh_port_info(self) -> None:
"""Refresh the port information"""
await self._populate_ports()
await self._update_lldp()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I know this was more a reshuffle than a feature update, but worth asking

  • Do these two steps need to be run sequentially?
  • Or can they happen ~simultaneously?

I was typing up a suggestion to use asyncio.gather, but that looked needlessly complicated compared to what it here. So... 🤷

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like it could happen simultaneously.

Comment thread src/switch_exporter/scraper.py Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants