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

std/asyncfile is not async. Documentation don't mention it #23461

Open
Alogani opened this issue Mar 29, 2024 · 1 comment
Open

std/asyncfile is not async. Documentation don't mention it #23461

Alogani opened this issue Mar 29, 2024 · 1 comment
Labels
Documentation Content Related to documentation content (not generation). Feature

Comments

@Alogani
Copy link

Alogani commented Mar 29, 2024

Description

Hello,

std/asyncfile implementation is not truly async because it doesn't use selectors (at least on Unix. I don't know on Windows).
The documentation don't mention it, resulting in deceptive behaviour

This is not a problem for regular files. But it's problematic for fifo, pipes, etc. For example, creating an asyncfile from stdin won't have the expected behaviour, because the call will be blocking the main thread.

Nim Version

2.0.2

Current Output

No response

Expected Output

No response

Possible Solution

The solution is to modify the current implementation to use for example addRead before reading asyncfile. For epoll, using addRead on regular file will raise an error.

Here are some proposal from some of my own library :

proc readSelect(self: AsyncFile): Future[void] =
    result = self.readListener.wait()
    if not self.pollable or self.readListener.isListening():
        return
    if bool(self.cancelled):
        self.readListener.trigger()
        return
    self.readListener.clear()
    proc cb(fd: AsyncFD): bool {.closure gcsafe.} =
        self.readListener.trigger()
        true
    AsyncFD(self.fd).addRead(cb)
## Or simpler, but could result in multiple callbacks for same AsyncFd :
proc readSelect(self: AsyncFile): Future[void] =
    var fut = newFuture[void]()
    proc cb(fd: AsyncFD): bool {.closure gcsafe.} =
        var fut.complete
        true
    AsyncFD(self.fd).addRead(cb)
    return fut
## Solution on Unix only
proc isPollable(fd: cint): bool =
    ## EPOLL will throw error on regular file and /dev/null (warning: /dev/null not checked)
    ## Solution: no async on regular file
    var stat: Stat
    discard fstat(fd, stat)
    not S_ISREG(stat.st_mode)

Additional Information

No response

@Araq
Copy link
Member

Araq commented Mar 29, 2024

On Windows it is async.

@juancarlospaco juancarlospaco added Feature Documentation Content Related to documentation content (not generation). labels Mar 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Documentation Content Related to documentation content (not generation). Feature
Projects
None yet
Development

No branches or pull requests

3 participants