From d317e8f6df0e0e16445db606da1d683a6b35f531 Mon Sep 17 00:00:00 2001 From: Alexander Neonxp Kiryukhin Date: Tue, 30 Dec 2025 19:33:39 +0300 Subject: =?UTF-8?q?=D0=BD=D0=B0=D1=87=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D0=B9?= =?UTF-8?q?=20=D0=BA=D0=BE=D0=BC=D0=BC=D0=B8=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/chat/chan.go | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 internal/chat/chan.go (limited to 'internal/chat/chan.go') diff --git a/internal/chat/chan.go b/internal/chat/chan.go new file mode 100644 index 0000000..ae78bb6 --- /dev/null +++ b/internal/chat/chan.go @@ -0,0 +1,69 @@ +package chat + +import ( + "context" + "log/slog" + "sync" + "time" +) + +type Channel struct { + Name string + Users map[*User]struct{} + Events chan any + mu sync.RWMutex +} + +func (c *Channel) Listen(ctx context.Context) { + for { + select { + case <-ctx.Done(): + return + case ev := <-c.Events: + c.processEvent(ev) + } + } +} + +func (c *Channel) processEvent(ev any) { + slog.Info("channel event", slog.String("channel", c.Name), slog.Any("event", ev)) + + for u := range c.Users { + select { + case u.Events <- ev: + default: + } + } +} + +func (c *Channel) Join(u *User) { + c.mu.Lock() + defer c.mu.Unlock() + + if _, ok := c.Users[u]; ok { + return + } + c.Events <- UserJoined{ + User: u, + Time: time.Now(), + Chan: c, + } + + c.Users[u] = struct{}{} +} + +func (c *Channel) Leave(u *User) { + c.mu.Lock() + defer c.mu.Unlock() + + if _, ok := c.Users[u]; !ok { + return + } + c.Events <- UserLeft{ + User: u, + Time: time.Now(), + Chan: c, + } + + delete(c.Users, u) +} -- cgit v1.2.3