Filesystem event notification library on steroids. (under active development)
Documentation
godoc.org/github.com/rjeczalik/notify
Installation
~ $ go get -u github.com/rjeczalik/notify
Projects using notify
Filesystem event notification library on steroids. (under active development)
Documentation
godoc.org/github.com/rjeczalik/notify
Installation
~ $ go get -u github.com/rjeczalik/notify
Projects using notify
This commit changes Event type and makes it quite similar to Signal types/interface from std library:
os - defines a Signal interface.
os/signal - uses os.Signal interface.
syscall - defines and declares Signal type which fulfills os.Signal interface. The syscall.Signal type has different impl for each platform.
os - should define an Event (Notify) interface
os/notify - should contain the rjmagicwtf implementation which uses os.Event interface + platform dependent impl for watchers.
syscall - defines Event type per each platform...
I didn't create an Event interface because I'm too lazy to fix @rjeczalik 's code which will break after such changes xD
Implement it with by calling epoll_pwait(). According to man epoll_pwait, calling epoll_pwait with sigmask of NULL is identical to epoll_wait.
Bring the fixes from golang.org/x/sys/unix to support these transparently on arm64.
This is needed to fix https://github.com/minio/mc/issues/2047
notify.Error(ch) error
:ch := make(chan notify.EventInfo)
notify.Watch("/home/pknap/.secretporndir", ch, notify.Delete)
switch ei, ok := <-ch; {
case ei.Event() == notify.Delete:
fmt.Printf("Who deleted my %s file?;/\n", ei.Name())
case !ok:
fmt.Println("wtf: %v", notify.Error(ch))
}
[edit] The 1 option can look better:
ch := make(chan notify.EventInfo)
notify.Watch("/home/pknap/.secretporndir", ch, notify.Delete)
switch ei, ok := <-ch; ei.Event() {
case notify.Delete:
fmt.Printf("Who deleted my %s file?;/\n", ei.Name())
default:
if !ok {
fmt.Println("wtf: %v", notify.Error(ch))
}
}
type notifyError error
func (e *notifyError) Event() Event { ... }
func (e *notifyError) IsDir() bool { ... }
func (e *notifyError) Name() string { ... }
func (e *notifyError) Sys() interface{} { ... }
func (e *notifyError) Err() error { ... } // Extra method:>
then:
ch := make(chan notify.EventInfo)
notify.Watch("/home/pknap/rottenbodies", ch, notify.Delete)
switch ei := <-ch; ei.Event() {
case notify.Delete:
fmt.Printf("Who deleted my %s file?;/\n", ei.Name())
default: // need to have all registered events in case statement or check `ei.Err() != nil` after `default`
fmt.Println("wtf: %v", ei.Err())
}
Other ideas?
questionSee https://tip.golang.org/doc/go1.6#cgo for background.
Using Go 1.6rc2 with github.com/cortesi/modd
immediately generates a panic from within this library. To reproduce:
go get -u github.com/cortesi/modd/cmd/modd
modd.conf
that contains * {}
.Result:
panic: runtime error: cgo argument has Go pointer to Go pointer
goroutine 1 [running]:
github.com/rjeczalik/notify.(*stream).Start(0xc820012700, 0x0, 0x0)
$GOPATH/src/github.com/rjeczalik/notify/watcher_fsevents_cgo.go:131 +0x270
github.com/rjeczalik/notify.(*fsevents).watch(0xc8200742c0, 0xc82000e7e0, 0x17, 0x100001b00, 0x0, 0x0)
$GOPATH/src/github.com/rjeczalik/notify/watcher_fsevents.go:206 +0x313
github.com/rjeczalik/notify.(*fsevents).RecursiveWatch(0xc8200742c0, 0xc82000e7e0, 0x17, 0x1b0000001b00, 0x0, 0x0)
$GOPATH/src/github.com/rjeczalik/notify/watcher_fsevents.go:258 +0x51
go.(*struct { github.com/rjeczalik/notify.watcher; github.com/rjeczalik/notify.recursiveWatcher }).RecursiveWatch(0xc820086140, 0xc82000e7e0, 0x17, 0xc800001b00, 0x0, 0x0)
<autogenerated>:50 +0x7c
github.com/rjeczalik/notify.(*recursiveTree).Watch(0xc8200880a0, 0xc82000e7e0, 0x17, 0xc8200a86c0, 0xc82000aaa8, 0x1, 0x1, 0x0, 0x0)
$GOPATH/src/github.com/rjeczalik/notify/tree_recursive.go:286 +0xad6
github.com/rjeczalik/notify.Watch(0xc82000aaa0, 0x5, 0xc8200a86c0, 0xc82000aaa8, 0x1, 0x1, 0x0, 0x0)
$GOPATH/src/github.com/rjeczalik/notify/notify.go:64 +0x7d
github.com/cortesi/modd/watch.Watch(0xc82000e780, 0x2, 0x2, 0x5f5e100, 0xc8200a84e0, 0xc82000e780, 0x0, 0x0)
$GOPATH/src/github.com/cortesi/modd/watch/watch.go:301 +0x145
github.com/cortesi/modd.runOnChan(0xc8200a84e0, 0x4383390, 0x4b002f0, 0xc820012600, 0xc82000e680, 0x4307bb0, 0xb, 0xc82004fdb8, 0x0, 0x0, ...)
$GOPATH/src/github.com/cortesi/modd/modd.go:89 +0x4d6
github.com/cortesi/modd.Run(0x4b002f0, 0xc820012600, 0xc82000e680, 0x4307bb0, 0xb, 0xc82004fdb8, 0x0, 0x0, 0x4013277, 0x0, ...)
$GOPATH/src/github.com/cortesi/modd/modd.go:141 +0xbe
main.main()
$GOPATH/src/github.com/cortesi/modd/cmd/modd/main.go:102 +0x9a2
bug
Hey Rafal, I'm running into a weird issue with watching, where lot of events are dropped when the files are created in a rapid succession, ie using for f in {0..10}; do echo $f > "$f.txt"; done
Here's the code I'm using:
package main
import (
"github.com/rjeczalik/notify"
"log"
)
func main() {
c := make(chan notify.EventInfo)
if err := notify.Watch("<folder>", c, notify.All); err != nil {
log.Fatal(err)
}
defer notify.Stop(c)
var index = 0
for {
ei := <-c
index += 1
if ei.Event() == notify.Create{
log.Println("Got event:", ei, index)
}
}
}
I tried the same with fsnotify
and I'm not noticing any drop there:
package main
import (
"gopkg.in/fsnotify.v1"
"log"
)
func main() {
watcher, err := fsnotify.NewWatcher()
if err != nil {
log.Fatal(err)
}
defer watcher.Close()
var index = 0
done := make(chan bool)
go func() {
for {
select {
case event := <-watcher.Events:
if event.Op&fsnotify.Write == fsnotify.Write {
index += 1
log.Println("modified file:", event.Name, index)
}
case err := <-watcher.Errors:
log.Println("error:", err)
}
}
}()
if err = watcher.Add("<folder>"); err != nil {
log.Fatal(err)
}
<-done
}
If I added a bit of sleep (0.1s) between file creation, all the events are received. I tested it on Ubuntu (Koding VM).
Regards.
docThe issue is incomming integration tests would need to instantiate and terminate multiple watcher instances via NewWatcher
. As long as inotify
is implemented using single global and single syscall.InotifyInit
this would break those tests.
There is no guarantee that integration tests for error handling would be capable to do full and proper cleanup of the global inotify
instance, and it's obvious what happens next when a test is not idempotent to a Watcher.
Moreover running tests in parallel would not be possible without it.
enhancement help wantedCoreFoundation run loops are tied to a particular thread. The goroutine that sets up the run loop may get rescheduled on a different thread just after adding the source. In that case the run loop that's started wouldn't have any sources and thus exit immediately.
Fix this by locking the goroutine to its thread. The thread is wasted on the run loop anyway, so we might as well claim it earlier.
Should help with #139
This started in issue #124 and replaces the previously split up PRs. This is bundled as the fixed problems come up in the same tests, but are in separate commits to make each change-diff about a single problem. The commits should explain what is going on.
Hi, I am trying to use notify
to listen to CREATE
events in a volume mounted over ZFS in a server running FreeBSD.
But the event does not get captured at all. The code works fine in my Ubuntu distribution.
Any idea why? Thanks!
bugThis way you can stop watching only specified events, what is necessary and makes it work as comment says.
It does not change how current implementations work (they ignore the value, and passed is always All
), but allows it to be utilized.
The thing I did to fix compatibility for Go 1.10 has been changed again on the Go tree since. To actually build with go1.10rc1 we need to revert my thing. Sorry.
This reverts commit ff2d4d2cedc09db23cc46d3eeb8b402bca6d819d.
cgo-gcc-prolog:217:2: warning: 'FSEventStreamScheduleWithRunLoop' is deprecated: first deprecated in macOS 13.0 - Use FSEventStreamSetDispatchQueue instead. [-Wdeprecated-declarations]
FSEventStreamScheduleWithRunLoop(
FSEventStreamRef streamRef,
CFRunLoopRef runLoop,
CFStringRef runLoopMode) API_DEPRECATED("Use FSEventStreamSetDispatchQueue instead.", macos(10.5, 13.0), ios(6.0,16.0));
extern void
FSEventStreamSetDispatchQueue(
FSEventStreamRef streamRef,
dispatch_queue_t __nullable q) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_6_0);
Sadly, I tried to modify it and it didn't work
Hello! This PR fixes 3 problems we encountered in the recursive tree watcher implementation and adds 2 new tests:
package main
import (
"fmt"
"io/ioutil"
"os"
"github.com/rjeczalik/notify"
)
func watch(path string) chan notify.EventInfo {
c := make(chan notify.EventInfo, 1)
if err := notify.Watch(path+"...", c, notify.All); err != nil {
panic(err)
}
return c
}
func main() {
os.MkdirAll("./a/b/c", 0775)
defer os.RemoveAll("./a")
// watch a child and parent path across multiple channels. This can happen in any order.
ch1 := watch("./a/b")
ch2 := watch("./a/b/c")
// unwatch ./a/b/c -- this is what triggers unwatching of ./a/b as well
notify.Stop(ch2)
// fire an event that will never show up because the path a/b is now unwatched
go func() { ioutil.WriteFile("a/b/c/d", []byte("X"), 0664) }()
// Never terminates
fmt.Println(<-ch1)
}
I added a new test called TestStopChild
that tests explicitly for this problem.
TestAddParentAfterStop
that tests explicitly for this problem. With the fixes introduced in this PR, the code snippet in #155 runs fine without any panicsStop()
, RecursiveUnwatch
is never called, because watchIsRecursive(nd)
is called after the watchpoint was already removed and hence the check always returns that the watch is not recursiveThe README for this project says it is "under active development", and positions it as "on steroids" (presumably as opposed to the more widely used fsnotify
package). Is it still under active development?
This does not compile on Solaris due to C.FILE_TRUNC missing.
.../go/pkg/mod/github.com/syncthing/[email protected]/watcher_fen_cgo.go:30:25: could not determine kind of name for C.FILE_TRUNC
hi, when I build a project which depends on notify in mac osx 10.15 , it gets below error
the detail step is described here: would you please to check: https://github.com/ethereum/go-ethereum/issues/21835
error info
# github.com/rjeczalik/notify
../../pkg/mod/github.com/rjeczalik/[email protected]/watcher_fsevents_cgo.go:10:10: fatal error: 'CoreServices/CoreServices.h' file not found
#include <CoreServices/CoreServices.h>
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../pkg/mod/github.com/rjeczalik/[email protected]/watcher_fsevents_cgo.go:10:10: note: did not find header 'CoreServices.h' in framework 'CoreServices' (loaded from '/System/Library/Frameworks')
1 error generated.
Changes:
This is an artificial release, just to start tagging notify properly from now on.
Source code(tar.gz)Shoutrrr Notification library for gophers and their furry friends. Heavily inspired by caronc/apprise. Quick Start As a package Using shoutrrr is easy
Apple Push Notification (APN) Provider library for Go 1.6 and HTTP/2. Send remote notifications to iOS, macOS, tvOS and watchOS. Buford can also sign push packages for Safari notifications and Wallet passes.
stargazers Features monitor the star events of the GitHub repo send the notifications to Slack or Lark How to use For Lark, create a bot called like s
eventsocket FreeSWITCH Event Socket library for the Go programming language. It supports both inbound and outbound event socket connections, acting ei
Event Sourcing for Go Idiomatic library to help you build Event Sourced application in Go. Please note The library is currently under development and
Atmo + NATS Example Project This repo is an example of using Atmo with NATS as a streaming messaging layer. In this example, Atmo connects to NATS and
The kprobe package allows construction of dynamic struct based on kprobe event format descriptions.
?? Eye Eye 是一个简单易用的事件驱动模式库。 Read me in English ?? 功能特性 敬请期待。。。 历史版本的特性请查看 HISTOR
File system notifications for Go fsnotify utilizes golang.org/x/sys rather than syscall from the standard library. Ensure you have the latest version
go-firebase-storage -Work in progress ??️ Simple Golang API that uses Firebase as its backend to demonstrate various firebase services using Go such a
About hclmergetool Works with HashiCorp HCL. Allows to append the input file with blocks and attributes from the template file Installation Binary Rel
Package stats Package stats allows for gathering of statistics regarding your Go application and system it is running on and sent them via UDP to a se
Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments Features Real-time Online/Offline Charging System (OCS). Account Balance
Gotgo This document describes the third iteration of my attempt at a reasonable implementation of generics for go based on the idea of template packag
Mobile Blogging System
Safebox An unified key management system to make life easier. The main goal of safebox is to make key backup easier with single main key to derive the
Entitas-Go Entitas-GO is a fast Entity Component System Framework (ECS) Go 1.17 port of Entitas v1.13.0 for C# and Unity. Code Generator Install the l
Lithia is an experimental functional programming language with an implicit but strong and dynamic type system. Lithia is designed around a few core concepts in mind all language features contribute to.
mock-billing-cli A golang application to mock the billing system in super markets Features View all items & items with filter Refill items with admin