Code Monkey home page Code Monkey logo

notifykit's Issues

Listen to events via I/O multiplexing

We are using sync approach to listening to events which works but there is one caveat. We had to interrupt after some time to see if we had not received a termination signal yet:

https://github.com/roma-glushko/inotifykit/blob/e3097ce41826908ec8f33c51c5b27afb33f02567/src/lib.rs#L38

So essentially, we are polling signal info instead of being notified when it happened.

Let's try to explore asynchronous approach to event watching/signal handling to save even more CPU cycles.

Incorporate the debouncer logic to extend it in a notifykit way

I'm thinking of incorporating the full debouncer logic to extend it a way notifykit usecases require.

For now, there are a few benefits from that:

  • keep one single thread to process raw notify-rs events
  • bring better async support
  • ability to address bugs like #10
  • expose more information in notifykit events potentially useful for end consumers (e.g. detection time, inode ID, etc.)

Events are not matched by match statement

Right now, it's not match statement ignores Event classes when trying to match them there.

Also, we need to allowlist attributes like path, access_mode, etc, to be matched by the statement. It's not disallowed by default.

Asynchronously adding watches blocks at `notifier.watch`

I tested out notifykit as it seems to promising alternative to watchdog (which has all sorts of issues).

Alas, I run into an issue in one of my first experiments:

#!/usr/bin/env python
import asyncio
import os

from notifykit import Notifier


async def manage_watches(notifier):
    for i in range(10):
        path = f"./subdir{i:04d}"
        if not os.path.isdir(path):
            os.mkdir(path)
        print("BEFORE", path)
        notifier.watch([path])
        print("AFTER", path)
        await asyncio.sleep(0.01)


async def watch() -> None:
    notifier = Notifier(debounce_ms=200, debug=True)
    task = asyncio.create_task(manage_watches(notifier))
    async for event in notifier:
        print(event)
    await task


if __name__ == "__main__":
    asyncio.run(watch())

This example simulates the use case of a more complex asynchrounous program, where one task is responsible for adding (and removing watches) while another task is responsible for acting upon events.

When running this example, I get the following output before the script blocks:

BEFORE ./subdir0000
watcher: INotifyWatcher { channel: Sender { .. }, waker: Waker { inner: Waker { waker: WakerInternal { fd: File { fd: 8, path: "anon_inode:[eventfd]", read: true, write: true } } } } }
AFTER ./subdir0000
BEFORE ./subdir0001

It seems that adding watches while iterating over the notifier is not allowed. Adding the watches before is not a problem, but that is not my use case. (The recursive option is also not useful for the case on which this example is based, because it has a more complicated set of rules to decide which directories to (un)watch.)

[Design] Cross-platform Event API

Event though we are using notify-rs (that supports inotify-like watches across various platforms like macOS, Linux, Windows, etc) library in inotifykit, it's still tricky to get fully cross-platform API.

The problem is in events/information that different platform support. For example,

  • some platforms support file metadata change events and some not
  • some platforms emits rename as a separate event and some emits two events instead (old file deletion + new file creation)
  • etc.

Because of this discrepancies in how events are dispatched, it still requires some work to smooth that experience to make it resemble a real platform-agnostic API.

It would be great to put that heavy-lifting on inotifykit, so our users could really focus on their business logic.

Solution

It seems like a way to go is to find a common ground between all supported file watcher's API and unify it on the library level.

One ramification of this is that we would need to hide some of the events or information that is not widely supported by all watchers. it seems like a reasonable limitation as if you had an access to that information, it would be impossible to run that code on the platform that didn't support it (so we would break our cross-platform promise).

This behavior should be optional, so people that needs missing info and don't need true cross-platform support would be able to have that.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.