Skip to content

Remove global clients #1014

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 52 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
90cce2c
fix
dido18 Jan 20, 2025
c96490b
feat(config): add default configuration file and update config handling
dido18 Jan 21, 2025
7b4859a
fix(.gitignore): add entry to ignore config.ini file
dido18 Jan 21, 2025
279de2a
test(config): add test for writing default config.ini file and update…
dido18 Jan 21, 2025
4f3ac5a
test(config): add tests for retrieving config paths from XDG_CONFIG_H…
dido18 Jan 21, 2025
c41b815
feat(config): pass config path to main loop and update handling
dido18 Jan 22, 2025
55ca9e5
remove global systray
dido18 Jan 22, 2025
f07103e
WIP: remove hub and sh globals
dido18 Jan 22, 2025
ef94d97
remove global clients: use callback to avoid nesting import
dido18 Jan 24, 2025
d2d3aa6
feat(workflow): add Go installation step to release workflow
dido18 Mar 31, 2025
640e644
refactor: rename variable 'h' to 'hub' for clarity in main.go and upd…
dido18 Mar 31, 2025
99f8235
docs: add comments to clarify functions and handlers in config, hub, …
dido18 Mar 31, 2025
5e2161e
refactor: rename 'hub' and 'serialhub' types to 'Hub' and 'Serialhub'…
dido18 Mar 31, 2025
910bac2
refactor: rename 'Hub' and 'Serialhub' types to 'hub' and 'serialhub'…
dido18 Mar 31, 2025
17ed6b3
revert config changes
dido18 Mar 31, 2025
96f0f51
refactor: update logger handling and improve config path management
dido18 Mar 31, 2025
36af1ed
remove globas tools and index
dido18 Mar 31, 2025
f939e32
refactor: enhance logging mechanism by implementing logWriter and upd…
dido18 Apr 1, 2025
e22281f
remove log websocket
dido18 Apr 1, 2025
3bbf371
remove unused global clients comment from hub struct
dido18 Apr 1, 2025
0773f99
refactor: integrate systray into hub structure and update newHub func…
dido18 Apr 1, 2025
9c2ca54
pass tests
dido18 Apr 1, 2025
7e73b6c
Merge branch 'main' into remove-global-clients
dido18 Apr 1, 2025
fc51194
chore: add comment regarding potential removal of sysStray dependencies
dido18 Apr 1, 2025
8106c84
feat: move serial port into new file
dido18 Apr 2, 2025
4dba1a8
feat: add serialhub implementation for managing serial ports
dido18 Apr 2, 2025
7ea21c0
refactor: remove serialhub parameter from newHub function and instant…
dido18 Apr 2, 2025
a152b02
feat: move `spErr` `spClose` `spWrite` into hub (from serialhub)
dido18 Apr 2, 2025
fac0b10
refactor: remove newSerialHub instantiation from hub initialization i…
dido18 Apr 2, 2025
f04d5cc
move `spHandlerOpen` to hub from serialport.go
dido18 Apr 2, 2025
47213d1
refactor: remove unused serial package import from serialport.go
dido18 Apr 2, 2025
14ddd43
renamed h into hub
dido18 Apr 2, 2025
1f9b999
fix: add hub reference to PLogger initialization in uploadHandler
dido18 Apr 2, 2025
4585769
move `spErr, spWrite, spClose spHandlerOpen at the end for redaibility
dido18 Apr 2, 2025
283064c
refactor: clean up serialport.go and serialportlist.go for clarity
dido18 Apr 2, 2025
14d72e8
refactor: clarify the impact of removing serialPorts.List() in writer…
dido18 Apr 2, 2025
9e13dcb
move serialportlist inside hub
dido18 Apr 2, 2025
a69c0dc
refactor on callback
dido18 Apr 2, 2025
7e34071
refactor: simplify hub initialization in upload handler tests
dido18 Apr 3, 2025
815a791
refactor: remove unused port listing in checkCmd function
dido18 Apr 3, 2025
9535905
rename into `h` and revert split of serial.go
dido18 Apr 16, 2025
0699e93
refactor: rename hub parameter in send and wsHandler functions for cl…
dido18 Apr 16, 2025
062bca0
refactor: move spHandlerOpen function from serialport.go to hub.go fo…
dido18 Apr 16, 2025
2bcc06d
remove comment
dido18 Apr 16, 2025
4da1624
refactor: remove unused serialPorts variable and instance of serialhu…
dido18 Apr 16, 2025
effe50d
remove commented-out spHandlerClose call in FindPortByName for cleane…
dido18 Apr 16, 2025
d68fc7a
fix: correct GitHub link in comment for clarity
dido18 Apr 16, 2025
fd3b2d7
refactor: replace logWriter with ChanWriter for improved logging mech…
dido18 Apr 16, 2025
0370591
refactor: move spErr, spWrite, and spClose functions from serial.go t…
dido18 Apr 16, 2025
a50aa86
refactor: remove logger from comment
dido18 Apr 16, 2025
65218a6
refactor: replace OnMessage with ChanWriter for improved message hand…
dido18 Apr 16, 2025
9cbe49e
fix tests
dido18 Apr 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion config/config.ini
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ updateUrl = https://downloads.arduino.cc/
origins = https://local.arduino.cc:8000
#httpProxy = http://your.proxy:port # Proxy server for HTTP requests
crashreport = false # enable crashreport logging
autostartMacOS = true # the Arduino Create Agent is able to start automatically after login on macOS (launchd agent)
autostartMacOS = true # the Arduino Create Agent is able to start automatically after login on macOS (launchd agent)
20 changes: 11 additions & 9 deletions conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"os"
"path/filepath"

"github.com/arduino/arduino-create-agent/tools"
"github.com/arduino/arduino-create-agent/upload"
"github.com/arduino/arduino-create-agent/utilities"
"github.com/gin-gonic/gin"
Expand Down Expand Up @@ -80,7 +81,7 @@ type Upload struct {

var uploadStatusStr = "ProgrammerStatus"

func uploadHandler(pubKey *rsa.PublicKey) func(*gin.Context) {
func uploadHandler(h *hub, pubKey *rsa.PublicKey, tools *tools.Tools) func(*gin.Context) {
return func(c *gin.Context) {
data := new(Upload)
if err := c.BindJSON(data); err != nil {
Expand Down Expand Up @@ -162,9 +163,9 @@ func uploadHandler(pubKey *rsa.PublicKey) func(*gin.Context) {

go func() {
// Resolve commandline
commandline, err := upload.PartiallyResolve(data.Board, filePath, tmpdir, data.Commandline, data.Extra, Tools)
commandline, err := upload.PartiallyResolve(data.Board, filePath, tmpdir, data.Commandline, data.Extra, tools)
if err != nil {
send(map[string]string{uploadStatusStr: "Error", "Msg": err.Error()})
send(h, map[string]string{uploadStatusStr: "Error", "Msg": err.Error()})
return
}

Expand All @@ -174,16 +175,16 @@ func uploadHandler(pubKey *rsa.PublicKey) func(*gin.Context) {
if data.Extra.Network {
err = errors.New("network upload is not supported anymore, pease use OTA instead")
} else {
send(map[string]string{uploadStatusStr: "Starting", "Cmd": "Serial"})
send(h, map[string]string{uploadStatusStr: "Starting", "Cmd": "Serial"})
err = upload.Serial(data.Port, commandline, data.Extra, l)
}

// Handle result
if err != nil {
send(map[string]string{uploadStatusStr: "Error", "Msg": err.Error()})
send(h, map[string]string{uploadStatusStr: "Error", "Msg": err.Error()})
return
}
send(map[string]string{uploadStatusStr: "Done", "Flash": "Ok"})
send(h, map[string]string{uploadStatusStr: "Done", "Flash": "Ok"})
}()

c.String(http.StatusAccepted, "")
Expand All @@ -193,6 +194,7 @@ func uploadHandler(pubKey *rsa.PublicKey) func(*gin.Context) {
// PLogger sends the info from the upload to the websocket
type PLogger struct {
Verbose bool
h *hub
}

// Debug only sends messages if verbose is true (always true for now)
Expand All @@ -206,15 +208,15 @@ func (l PLogger) Debug(args ...interface{}) {
func (l PLogger) Info(args ...interface{}) {
output := fmt.Sprint(args...)
log.Println(output)
send(map[string]string{uploadStatusStr: "Busy", "Msg": output})
send(l.h, map[string]string{uploadStatusStr: "Busy", "Msg": output})
}

func send(args map[string]string) {
func send(h *hub, args map[string]string) {
mapB, _ := json.Marshal(args)
h.broadcastSys <- mapB
}

func wsHandler() *WsServer {
func wsHandler(h *hub) *WsServer {
server, err := socketio.NewServer(nil)
if err != nil {
log.Fatal(err)
Expand Down
122 changes: 89 additions & 33 deletions hub.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import (
"strconv"
"strings"

"github.com/arduino/arduino-create-agent/systray"
"github.com/arduino/arduino-create-agent/tools"
"github.com/arduino/arduino-create-agent/upload"
log "github.com/sirupsen/logrus"
)
Expand All @@ -45,14 +47,47 @@ type hub struct {

// Unregister requests from connections.
unregister chan *connection

// Serial hub to communicate with serial ports
serialHub *serialhub

serialPortList *serialPortList

tools *tools.Tools

systray *systray.Systray
}

var h = hub{
broadcast: make(chan []byte, 1000),
broadcastSys: make(chan []byte, 1000),
register: make(chan *connection),
unregister: make(chan *connection),
connections: make(map[*connection]bool),
func newHub(serialhub *serialhub, serialList *serialPortList, tools *tools.Tools, systray *systray.Systray) *hub {
hub := &hub{
broadcast: make(chan []byte, 1000),
broadcastSys: make(chan []byte, 1000),
register: make(chan *connection),
unregister: make(chan *connection),
connections: make(map[*connection]bool),
serialHub: serialhub,
serialPortList: serialList,
tools: tools,
systray: systray,
}

hub.serialHub.OnRegister = func(port *serport) {
hub.broadcastSys <- []byte("{\"Cmd\":\"Open\",\"Desc\":\"Got register/open on port.\",\"Port\":\"" + port.portConf.Name + "\",\"Baud\":" + strconv.Itoa(port.portConf.Baud) + ",\"BufferType\":\"" + port.BufferType + "\"}")
}

hub.serialHub.OnUnregister = func(port *serport) {
hub.broadcastSys <- []byte("{\"Cmd\":\"Close\",\"Desc\":\"Got unregister/close on port.\",\"Port\":\"" + port.portConf.Name + "\",\"Baud\":" + strconv.Itoa(port.portConf.Baud) + "}")
}

hub.serialPortList.OnList = func(data []byte) {
hub.broadcastSys <- data
}

hub.serialPortList.OnErr = func(err string) {
hub.broadcastSys <- []byte("{\"Error\":\"" + err + "\"}")
}

return hub
}

const commands = `{
Expand Down Expand Up @@ -108,7 +143,7 @@ func (h *hub) run() {
h.unregisterConnection(c)
case m := <-h.broadcast:
if len(m) > 0 {
checkCmd(m)
h.checkCmd(m)
h.sendToRegisteredConnections(m)
}
case m := <-h.broadcastSys:
Expand All @@ -117,7 +152,7 @@ func (h *hub) run() {
}
}

func checkCmd(m []byte) {
func (h *hub) checkCmd(m []byte) {
//log.Print("Inside checkCmd")
s := string(m[:])

Expand All @@ -132,18 +167,18 @@ func checkCmd(m []byte) {

args := strings.Split(s, " ")
if len(args) < 3 {
go spErr("You did not specify a port and baud rate in your open cmd")
go h.spErr("You did not specify a port and baud rate in your open cmd")
return
}
if len(args[1]) < 1 {
go spErr("You did not specify a serial port")
go h.spErr("You did not specify a serial port")
return
}

baudStr := strings.Replace(args[2], "\n", "", -1)
baud, err := strconv.Atoi(baudStr)
if err != nil {
go spErr("Problem converting baud rate " + args[2])
go h.spErr("Problem converting baud rate " + args[2])
return
}
// pass in buffer type now as string. if user does not
Expand All @@ -154,15 +189,15 @@ func checkCmd(m []byte) {
buftype := strings.Replace(args[3], "\n", "", -1)
bufferAlgorithm = buftype
}
go spHandlerOpen(args[1], baud, bufferAlgorithm)
go h.spHandlerOpen(args[1], baud, bufferAlgorithm)

} else if strings.HasPrefix(sl, "close") {

args := strings.Split(s, " ")
if len(args) > 1 {
go spClose(args[1])
go h.spClose(args[1])
} else {
go spErr("You did not specify a port to close")
go h.spErr("You did not specify a port to close")
}

} else if strings.HasPrefix(sl, "killupload") {
Expand All @@ -175,9 +210,9 @@ func checkCmd(m []byte) {

} else if strings.HasPrefix(sl, "send") {
// will catch send and sendnobuf and sendraw
go spWrite(s)
go h.spWrite(s)
} else if strings.HasPrefix(sl, "list") {
go serialPorts.List()
go h.serialPortList.List()
} else if strings.HasPrefix(sl, "downloadtool") {
go func() {
args := strings.Split(s, " ")
Expand Down Expand Up @@ -208,7 +243,12 @@ func checkCmd(m []byte) {
behaviour = args[4]
}

err := Tools.Download(pack, tool, toolVersion, behaviour)
reportPendingProgress := func(msg string) {
mapD := map[string]string{"DownloadStatus": "Pending", "Msg": msg}
mapB, _ := json.Marshal(mapD)
h.broadcastSys <- mapB
}
err := h.tools.Download(pack, tool, toolVersion, behaviour, reportPendingProgress)
if err != nil {
mapD := map[string]string{"DownloadStatus": "Error", "Msg": err.Error()}
mapB, _ := json.Marshal(mapD)
Expand All @@ -220,29 +260,45 @@ func checkCmd(m []byte) {
}
}()
} else if strings.HasPrefix(sl, "log") {
go logAction(sl)
go h.logAction(sl)
} else if strings.HasPrefix(sl, "restart") {
// potentially, the sysStray dependencies can be removed https://github.com/arduino/arduino-create-agent/issues/1013
log.Println("Received restart from the daemon. Why? Boh")
Systray.Restart()
h.systray.Restart()
} else if strings.HasPrefix(sl, "exit") {
Systray.Quit()
h.systray.Quit()
} else if strings.HasPrefix(sl, "memstats") {
memoryStats()
h.memoryStats()
} else if strings.HasPrefix(sl, "gc") {
garbageCollection()
h.garbageCollection()
} else if strings.HasPrefix(sl, "hostname") {
getHostname()
h.getHostname()
} else if strings.HasPrefix(sl, "version") {
getVersion()
h.getVersion()
} else {
go spErr("Could not understand command.")
go h.spErr("Could not understand command.")
}
}

func logAction(sl string) {
type logWriter struct {
onWrite func([]byte)
}

func (u *logWriter) Write(p []byte) (n int, err error) {
u.onWrite(p)
return len(p), nil
}

func (h *hub) logAction(sl string) {
if strings.HasPrefix(sl, "log on") {
*logDump = "on"
multiWriter := io.MultiWriter(&loggerWs, os.Stderr)

logWriter := logWriter{}
logWriter.onWrite = func(p []byte) {
h.broadcastSys <- p
}

multiWriter := io.MultiWriter(&logWriter, os.Stderr)
log.SetOutput(multiWriter)
} else if strings.HasPrefix(sl, "log off") {
*logDump = "off"
Expand All @@ -253,30 +309,30 @@ func logAction(sl string) {
}
}

func memoryStats() {
func (h *hub) memoryStats() {
var memStats runtime.MemStats
runtime.ReadMemStats(&memStats)
json, _ := json.Marshal(memStats)
log.Printf("memStats:%v\n", string(json))
h.broadcastSys <- json
}

func getHostname() {
func (h *hub) getHostname() {
h.broadcastSys <- []byte("{\"Hostname\" : \"" + *hostname + "\"}")
}

func getVersion() {
func (h *hub) getVersion() {
h.broadcastSys <- []byte("{\"Version\" : \"" + version + "\"}")
}

func garbageCollection() {
func (h *hub) garbageCollection() {
log.Printf("Starting garbageCollection()\n")
h.broadcastSys <- []byte("{\"gc\":\"starting\"}")
memoryStats()
h.memoryStats()
debug.SetGCPercent(100)
debug.FreeOSMemory()
debug.SetGCPercent(-1)
log.Printf("Done with garbageCollection()\n")
h.broadcastSys <- []byte("{\"gc\":\"done\"}")
memoryStats()
h.memoryStats()
}
23 changes: 13 additions & 10 deletions info.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"runtime"
"strings"

"github.com/arduino/arduino-create-agent/systray"
"github.com/gin-gonic/gin"
"go.bug.st/serial"
)
Expand All @@ -40,14 +41,16 @@ func infoHandler(c *gin.Context) {
})
}

func pauseHandler(c *gin.Context) {
go func() {
ports, _ := serial.GetPortsList()
for _, element := range ports {
spClose(element)
}
*hibernate = true
Systray.Pause()
}()
c.JSON(200, nil)
func pauseHandler(h *hub, s *systray.Systray) func(c *gin.Context) {
return func(c *gin.Context) {
go func() {
ports, _ := serial.GetPortsList()
for _, element := range ports {
h.spClose(element)
}
*hibernate = true
s.Pause()
}()
c.JSON(200, nil)
}
}
Loading
Loading