Skip to content

Commit

Permalink
event: refactor event API to support contexts
Browse files Browse the repository at this point in the history
  • Loading branch information
thiagokokada committed Sep 1, 2024
1 parent 8bc7481 commit 75d6218
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 10 deletions.
34 changes: 26 additions & 8 deletions event/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package event

import (
"bufio"
"context"
"fmt"
"net"
"strings"
Expand All @@ -22,23 +23,33 @@ const (
// If you need to connect to arbitrary user instances or need a method that
// will not panic on error, use [NewClient] instead.
func MustClient() *EventClient {
return assert.Must1(NewClient(helpers.MustSocket(".socket2.sock")))
return assert.Must1(NewClient(
context.Background(),
helpers.MustSocket(".socket2.sock"),
))
}

// Initiate a new event client.
// Receive as parameters a socket that is generally localised in
// '$XDG_RUNTIME_DIR/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock'.
func NewClient(socket string) (*EventClient, error) {
conn, err := net.Dial("unix", socket)
// The ctx ([context.Context]) parameter is passed to the underlying socket to
// allow cancellations and timeouts for the Hyprland event socket.
func NewClient(ctx context.Context, socket string) (*EventClient, error) {
dialer := &net.Dialer{}
conn, err := dialer.DialContext(ctx, "unix", socket)
if err != nil {
return nil, fmt.Errorf("error while connecting to socket: %w", err)
}
return &EventClient{conn: conn}, nil
return &EventClient{conn: conn, ctx: ctx}, err
}

// Close the underlying connection.
func (c *EventClient) Close() error {
return c.conn.Close()
err := c.conn.Close()
if err != nil {
return fmt.Errorf("error while closing socket: %w", err)
}
return err
}

// Low-level receive event method, should be avoided unless there is no
Expand All @@ -48,7 +59,7 @@ func (c *EventClient) Receive() ([]ReceivedData, error) {
reader := bufio.NewReader(c.conn)
n, err := reader.Read(buf)
if err != nil {
return nil, err
return nil, fmt.Errorf("error while reading from socket: %w", err)
}

buf = buf[:n]
Expand Down Expand Up @@ -79,11 +90,18 @@ func (c *EventClient) Receive() ([]ReceivedData, error) {
// the events you want to handle and all event types you want to handle.
func (c *EventClient) Subscribe(ev EventHandler, events ...EventType) error {
for {
subscribeOnce(c, ev, events...)
// The context is done, exit
if err := c.ctx.Err(); err != nil {
return fmt.Errorf("context is done: %w", err)
}
// Otherwise process an event
if err := receiveAndProcessEvent(c, ev, events...); err != nil {
return fmt.Errorf("error during event processing: %w", err)
}
}
}

func subscribeOnce(c eventClient, ev EventHandler, events ...EventType) error {
func receiveAndProcessEvent(c eventClient, ev EventHandler, events ...EventType) error {
msg, err := c.Receive()
if err != nil {
return err
Expand Down
2 changes: 1 addition & 1 deletion event/event_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func TestReceive(t *testing.T) {
func TestSubscribe(t *testing.T) {
h := &FakeEventHandler{t: t}
c := &FakeEventClient{}
err := subscribeOnce(c, h, AllEvents...)
err := receiveAndProcessEvent(c, h, AllEvents...)
assert.NoError(t, err)
}

Expand Down
6 changes: 5 additions & 1 deletion event/event_types.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package event

import "net"
import (
"context"
"net"
)

// EventClient is the event struct from hyprland-go.
type EventClient struct {
conn net.Conn
ctx context.Context
}

// Event Client interface, right now only used for testing.
Expand Down

0 comments on commit 75d6218

Please sign in to comment.