From 800df89b58577c761d6af2ab1715bb5d081aec6b Mon Sep 17 00:00:00 2001 From: Ivan Teterevkov Date: Fri, 6 May 2022 18:58:48 +0100 Subject: [PATCH] examples: Add asynchronous D-Bus client example Extend the server example with a Sleep method and add a client to demonstrate an asynchronous D-Bus call with possible timeout handling. --- _examples/server.go | 10 +++++++++ _examples/timeout.go | 51 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 _examples/timeout.go diff --git a/_examples/server.go b/_examples/server.go index f5464d9f..b300159a 100644 --- a/_examples/server.go +++ b/_examples/server.go @@ -3,6 +3,7 @@ package main import ( "fmt" "os" + "time" "github.com/godbus/dbus/v5" "github.com/godbus/dbus/v5/introspect" @@ -14,6 +15,9 @@ const intro = ` + + + ` + introspect.IntrospectDataString + ` ` type foo string @@ -23,6 +27,12 @@ func (f foo) Foo() (string, *dbus.Error) { return string(f), nil } +func (f foo) Sleep(seconds uint) *dbus.Error { + fmt.Println("Sleeping", seconds, "second(s)") + time.Sleep(time.Duration(seconds) * time.Second) + return nil +} + func main() { conn, err := dbus.ConnectSessionBus() if err != nil { diff --git a/_examples/timeout.go b/_examples/timeout.go new file mode 100644 index 00000000..e1deb96b --- /dev/null +++ b/_examples/timeout.go @@ -0,0 +1,51 @@ +package main + +import ( + "fmt" + "os" + "time" + + "github.com/godbus/dbus/v5" +) + +func main() { + conn, err := dbus.ConnectSessionBus() + if err != nil { + fmt.Fprintln(os.Stderr, "Failed to connect to session bus:", err) + os.Exit(1) + } + defer conn.Close() + + ch := make(chan *dbus.Call, 10) + + obj := conn.Object("com.github.guelfey.Demo", "/com/github/guelfey/Demo") + obj.Go("com.github.guelfey.Demo.Sleep", 0, ch, 5) // 5 seconds + + nrAttempts := 3 + isResponseReceived := false + + for i := 1; i <= nrAttempts && !isResponseReceived; i++ { + fmt.Println("Waiting for response, attempt", i) + + select { + case call := <-ch: + if call.Err != nil { + fmt.Fprintln(os.Stderr, "Failed to call Sleep method:", err) + os.Exit(1) + } + isResponseReceived = true + break + + // Handle timeout here + case <-time.After(2 * time.Second): + fmt.Println("Timeout") + break + } + } + + if isResponseReceived { + fmt.Println("Done!") + } else { + fmt.Fprintln(os.Stderr, "Timeout waiting for Sleep response") + } +}