Skip to content

Commit

Permalink
added: service discovery example with mdns (#34)
Browse files Browse the repository at this point in the history
  • Loading branch information
igumus authored May 5, 2023
1 parent 3cc6d83 commit 011a4bc
Show file tree
Hide file tree
Showing 12 changed files with 765 additions and 0 deletions.
42 changes: 42 additions & 0 deletions examples/mdns/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
PROJECT_BINARY=mdns
PROJECT_BINARY_OUTPUT=bin

.PHONY: all

all: help

## Build:
tidy: ## Tidy project
@go mod tidy

clean: ## Cleans temporary folder
@rm -rf ${PROJECT_BINARY_OUTPUT}
@rm -rf ${PROJECT_RELEASER_OUTPUT}

build: clean tidy build-arm build-amd ## Build all
@echo "DONE"

build-arm: ## Build for arm64
@GO111MODULE=on CGO_ENABLED=0 go build -ldflags="-w -s" -o ${PROJECT_BINARY_OUTPUT}/arm/${PROJECT_BINARY} main.go

build-amd: ## Build for amd64
@GO111MODULE=on CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -ldflags="-w -s" -o ${PROJECT_BINARY_OUTPUT}/amd/${PROJECT_BINARY} main.go

test: build ## Run unit tests
@go clean -testcache
@go test ./...

pre-commit: test ## Checks everything is allright
@echo "Commit Status: OK"

## Help:
help: ## Show this help.
@echo ''
@echo 'Usage:'
@echo ' make <target>'
@echo ''
@echo 'Targets:'
@awk 'BEGIN {FS = ":.*?## "} { \
if (/^[a-zA-Z_-]+:.*?##.*$$/) {printf " %-20s%s\n", $$1, $$2} \
else if (/^## .*$$/) {printf " %s\n", substr($$1,4)} \
}' $(MAKEFILE_LIST)
56 changes: 56 additions & 0 deletions examples/mdns/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Remote Engine Discovery via mDNS
This example shows us how service discovery can be done via mDNS.

# About
mDNS or Multicast DNS can be used to discover services on the local network without the use of an authoritative DNS server.
This enables peer-to-peer discovery. It is important to note that many networks restrict the use of multicasting, which prevents mDNS from functioning.
Notably, multicast cannot be used in any sort of cloud, or shared infrastructure environments.
However it works well in most office, home, or private infrastructure environments.

# Quickstart

> The **[examples](https://github.com/anthdm/hollywood/tree/master/examples/mdns)** folder is the best place to explore Hollywood's Service Discovery
```
make build
```

# Flow
0. When start engine with remote configuration, mDNS starting to announce itself and searches for other nodes
1. If node founds new engine, discovery actor publishes a `DiscoveryEvent` via `actor.EventStream`
2. (For demo purposes) An `chat` actor receives the discovery event and try to send a message to validate the flow.

# Execution

```
./bin/arm/mdns -port 4001
<omitted standart logs>
INFO[0000] [REMOTE] server started listenAddr="127.0.0.1:4001"
TRAC[0000] [EVENTSTREAM] subscribe id=1432518515 subs=1
TRAC[0000] [PROCESS] started pid="127.0.0.1:4001/chat"
TRAC[0000] [PROCESS] started pid="127.0.0.1:4001/mdns"
INFO[0001] [DISCOVERY] remote discovered ID=engine_1682994946742073000 addrs="127.0.0.1:4002"
TRAC[0001] [STREAM WRITER] connected remote="127.0.0.1:4002"
TRAC[0001] [STREAM ROUTER] new stream route pid="127.0.0.1:4001/stream/127.0.0.1:4002"
INFO[0001] new message fields.msg=hello
```
```
./bin/arm/mdns -port 4002
<omitted standart logs>
INFO[0000] [REMOTE] server started listenAddr="127.0.0.1:4002"
TRAC[0000] [EVENTSTREAM] subscribe id=1432518515 subs=1
TRAC[0000] [PROCESS] started pid="127.0.0.1:4002/chat"
TRAC[0000] [PROCESS] started pid="127.0.0.1:4002/mdns"
INFO[0000] [DISCOVERY] remote discovered ID=engine_1682994395132833000 addrs="127.0.0.1:4001"
TRAC[0000] [INBOX] started pid="127.0.0.1:4002/stream/127.0.0.1:4001"
TRAC[0000] [STREAM WRITER] connected remote="127.0.0.1:4001"
TRAC[0000] [STREAM ROUTER] new stream route pid="127.0.0.1:4002/stream/127.0.0.1:4001"
INFO[0000] new message fields.msg=hello
```

# References
- [mDNS](https://github.com/grandcat/zeroconf.git) library for golang

# License

Hollywood is licensed under the MIT licence.
56 changes: 56 additions & 0 deletions examples/mdns/chat/actor.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package chat

import (
"github.com/anthdm/hollywood/actor"
"github.com/anthdm/hollywood/examples/mdns/chat/types"
"github.com/anthdm/hollywood/examples/mdns/discovery"
"github.com/anthdm/hollywood/log"
)

type server struct {
eventStream *actor.EventStream
subscription *actor.EventSub
ctx *actor.Context
}

func New(e *actor.EventStream) actor.Producer {
return func() actor.Receiver {
ret := &server{
eventStream: e,
}
return ret
}
}

func (s *server) Receive(ctx *actor.Context) {
switch msg := ctx.Message().(type) {
case actor.Initialized:
s.ctx = ctx
s.subscription = s.eventStream.Subscribe(s.onMessage)
case actor.Started:
_ = msg
case actor.Stopped:
s.shutdown()
case *types.Message:
s.handleMessage(ctx, msg)
}
}
func (s *server) onMessage(event any) {
switch evt := event.(type) {
case *discovery.DiscoveryEvent:
pid := actor.NewPID(evt.Addr[0], "chat")
s.ctx.Engine().Send(pid, &types.Message{
Username: evt.ID,
Msg: "hello",
})
}
}

func (s *server) shutdown() {
s.eventStream.Unsubscribe(s.subscription)
}

// handle the incoming message by broadcasting it to all connected clients.
func (s *server) handleMessage(ctx *actor.Context, msg *types.Message) {
log.Infow("new message", log.M{"msg": msg.Msg})
}
Loading

0 comments on commit 011a4bc

Please sign in to comment.