Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for checking list of ip addresses #180

Closed
kengu opened this issue Feb 10, 2024 · 4 comments
Closed

Add support for checking list of ip addresses #180

kengu opened this issue Feb 10, 2024 · 4 comments

Comments

@kengu
Copy link
Contributor

kengu commented Feb 10, 2024

Rationale
My use case is presence detection ("arrive and leave home"). A service maintains a list of discovered devices on given subnet. Since ARP data is cached for some time after a device has disconnected from the network, I use this to determine if the device is available (respons to ping) or not (still in ARP cache). When a device is no longer in the ARP cache, the device is removed from the service.

Adding a truly new device to a network does not happen that often. Since the typical number of devices on a home network is much less then 256, and subnet-based discovery is a resource heavy operation for typical home network (default subnet is typically 256), it makes sense to implement an optimization for detecting if a specific (already discovered) device is available or not when the number of devices is much smaller than the subnet used. This would allow me to check availability more often (on a small number of devices) than the full subnet scan that will detect truly new devices.

Instead of implementing this my self by reimplementing the excellent solution using isolates already in place for subnet-based discovery, I would like to propose the following feature to be added to network_tools.

Proposal
Add a optional argument hostIds to existing discovery methods in HostScanner that subnet is evaluated against using hostId. This adds to existing logic without breaking it. This is how the method HostScanner.getAllPingableDevices signature would look like

 static Stream<ActiveHost> getAllPingableDevices(
    String subnet, {
    int firstHostId = defaultFirstHostId,
    int lastHostId = defaultLastHostId,
    List<int>? hostIds,
    int timeoutInSeconds = 1,
    ProgressCallback? progressCallback,
    bool resultsInAddressAscendingOrder = true,
  })

I'm already working on the implementation in my fork. If you would like to add this feature to network_tools, I'll make a pull-request when I'm done testing.

@kengu kengu changed the title Add support for checking list of ip adresses Add support for checking list of ip addresses Feb 10, 2024
kengu added a commit to kengu/network_tools that referenced this issue Feb 10, 2024
@guyluz11
Copy link
Collaborator

In general I think there should also be an option to unfunctions without isolate.

@kengu
Copy link
Contributor Author

kengu commented Feb 10, 2024

In general I think there should also be an option to unfunctions without isolate.

Did you mean adding hostIds to all these functions?

  • HostScanner.getAllPingableDevices
  • HostScanner.getAllPingableDevicesAsync
  • HostScanner.getAllSendablePingableDevices (is without isolate)

If yes, I've done that in this PR now.

The tests are also extended to test for include/exclude using hostIds argument

@guyluz11
Copy link
Collaborator

guyluz11 commented Feb 11, 2024

*run functions without isolate.

@kengu
Copy link
Contributor Author

kengu commented Feb 11, 2024

I've tested the implementation with my use-case using this pseduo-algorithm

fullEvery := 5 min
liveEvery := 1 min

start with full scan 
    for all discovered network devices
        store state (hostId, name, address, vendor, availability)

do liveEvery period
    if fullEvery period reached
        do full scan and update states
    else 
        do live scan and update states

My test network have around 20 connected devices with subnet /24 (which leads to 256 address checks per full scan). A full scan on my dev-machine (macos) takes about 30s using HostScanner.getAllPingableDevicesAsync, and a scan of only discovered devices takes about 20s (the sharding of addresses in chuncks of 51 is unmodified). The difference is in the amount CPU time the scan takes which is significant (number of ping-instances is significantly reduced from 51 per shard). This effect will of course be inverse proportional with the number of unike addresses on the network, the more devices the network have, the less reduction in CPU time you will see.

If the goal was to reduce the scan time, we would need to also change the sharding mechanism. This could be done by modifying scanRangeForIsolate in HostScanner.getAllPingableDevicesAsync to take into account the number of items in hostIds. Since I'm looking for minimizing the overall system load by spreading out the scan over time, this is not something I've looked into (yet). The solution could be as simple as increasing the shard size by implementing an inverse relationship with number of items in hostIds, making more of them fit into one or more shards depending on how much you would like to "pack" the scan.

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

No branches or pull requests

2 participants