Initial Commit (Read: Dirty AF)
This commit is contained in:
		
							
								
								
									
										18
									
								
								.pre-commit-config.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								.pre-commit-config.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					# See https://pre-commit.com for more information
 | 
				
			||||||
 | 
					# See https://pre-commit.com/hooks.html for more hooks
 | 
				
			||||||
 | 
					repos:
 | 
				
			||||||
 | 
					-   repo: https://github.com/pre-commit/pre-commit-hooks
 | 
				
			||||||
 | 
					    rev: v5.0.0
 | 
				
			||||||
 | 
					    hooks:
 | 
				
			||||||
 | 
					    -   id: trailing-whitespace
 | 
				
			||||||
 | 
					    -   id: end-of-file-fixer
 | 
				
			||||||
 | 
					    -   id: check-yaml
 | 
				
			||||||
 | 
					    -   id: check-added-large-files
 | 
				
			||||||
 | 
					-   repo: https://github.com/dnephin/pre-commit-golang
 | 
				
			||||||
 | 
					    rev: v0.5.1
 | 
				
			||||||
 | 
					    hooks:
 | 
				
			||||||
 | 
					      - id: go-fmt
 | 
				
			||||||
 | 
					      - id: go-imports
 | 
				
			||||||
 | 
					      - id: no-go-testing
 | 
				
			||||||
 | 
					      - id: golangci-lint
 | 
				
			||||||
 | 
					      - id: go-unit-tests
 | 
				
			||||||
@@ -1,3 +1,3 @@
 | 
				
			|||||||
# sfcs
 | 
					# sfcs
 | 
				
			||||||
 | 
					Sudoku-Funpark Cluster Software: same as [Sudoku-funpark](https://gitea.ligthert.net/golang/sudoku-funpark/), but networked.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Sudoku-Funpark Cluster Software: same as Sudoku-funpark, but networked.
 | 
					 | 
				
			||||||
							
								
								
									
										36
									
								
								Taskfile.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								Taskfile.yml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					# https://taskfile.dev
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					version: '3'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vars:
 | 
				
			||||||
 | 
					  APP: sudoku-funpark
 | 
				
			||||||
 | 
					  BUILD_DIR: builds
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tasks:
 | 
				
			||||||
 | 
					  default:
 | 
				
			||||||
 | 
					    cmds:
 | 
				
			||||||
 | 
					      - go run . --help
 | 
				
			||||||
 | 
					    silent: true
 | 
				
			||||||
 | 
					  precommit:
 | 
				
			||||||
 | 
					    cmds:
 | 
				
			||||||
 | 
					      - pre-commit autoupdate
 | 
				
			||||||
 | 
					      - pre-commit run --all
 | 
				
			||||||
 | 
					    silent: true
 | 
				
			||||||
 | 
					  lint:
 | 
				
			||||||
 | 
					    cmds:
 | 
				
			||||||
 | 
					      - golangci-lint run
 | 
				
			||||||
 | 
					    silent: true
 | 
				
			||||||
 | 
					  build:
 | 
				
			||||||
 | 
					    cmds:
 | 
				
			||||||
 | 
					      - mkdir -p {{.BUILD_DIR}}
 | 
				
			||||||
 | 
					      - rm {{.BUILD_DIR}}/* || true
 | 
				
			||||||
 | 
					      - go tool dist list | grep -v android | grep -v ios | grep -v wasip1 | awk -F '/' '{printf "echo Compiling %s/%s; env CGO_ENABLED=1 GOOS=%s GOARCH=%s go build -o {{.BUILD_DIR}}/{{.APP}}.%s-%s\n",$1,$2,$1,$2,$1,$2 }' | sh
 | 
				
			||||||
 | 
					      - for i in `ls {{.BUILD_DIR}}/*windows*`; do mv -v $i $i.exe; done
 | 
				
			||||||
 | 
					  gource:
 | 
				
			||||||
 | 
					    cmds:
 | 
				
			||||||
 | 
					      - gource --auto-skip-seconds 1 --key -r 60
 | 
				
			||||||
 | 
					    silent: true
 | 
				
			||||||
 | 
					  godoc:
 | 
				
			||||||
 | 
					    cmds:
 | 
				
			||||||
 | 
					      - godoc -http=:6060
 | 
				
			||||||
 | 
					    silent: true
 | 
				
			||||||
							
								
								
									
										6
									
								
								client/types.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								client/types.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					package client
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Client struct {
 | 
				
			||||||
 | 
						serverAddress string
 | 
				
			||||||
 | 
						serverPort    int
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										36
									
								
								flags/ParseFlags.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								flags/ParseFlags.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					package flags
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "flag"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (flags *Flags) ParseFlags() (err error) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Define parameters
 | 
				
			||||||
 | 
						flag.StringVar(&flags.Vars.Role, "role", "scheduler", "Role of the instance ['scheduler','agent']")
 | 
				
			||||||
 | 
						flag.StringVar(&flags.Vars.Address, "address", "127.0.0.1", "Address of the instance to listen to/connect to")
 | 
				
			||||||
 | 
						flag.IntVar(&flags.Vars.Port, "port", 8080, "Port of the instance to listen on/connect to")
 | 
				
			||||||
 | 
						flag.IntVar(&flags.Vars.NumCPUs, "numcpus", 1, "[agent] Number of CPUs to use")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Parse the flags
 | 
				
			||||||
 | 
						flag.Parse()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Parse the role parameters
 | 
				
			||||||
 | 
						err = flags.parseRole()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// Parse the number of CPUs parameters
 | 
				
			||||||
 | 
						err = flags.parseNumCPUs()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Parse the address and port parameters
 | 
				
			||||||
 | 
						err = flags.parseAddressPort()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Return nil if no errors
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										32
									
								
								flags/parseAddressPort.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								flags/parseAddressPort.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
				
			|||||||
 | 
					package flags
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"net"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (flags *Flags) parseAddressPort() (err error) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Ensure that address field is not empty
 | 
				
			||||||
 | 
						if flags.Vars.Address == "" {
 | 
				
			||||||
 | 
							return fmt.Errorf("Address cannot be empty")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Ensure that address field is valid IP address
 | 
				
			||||||
 | 
						if net.ParseIP(flags.Vars.Address) == nil {
 | 
				
			||||||
 | 
							return fmt.Errorf("GloVars must be a valid IP address")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Ensure that port field is not empty
 | 
				
			||||||
 | 
						if flags.Vars.Port == 0 {
 | 
				
			||||||
 | 
							return fmt.Errorf("Port cannot be empty")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Ensure that port field is within the valid range
 | 
				
			||||||
 | 
						if flags.Vars.Port < 1 || flags.Vars.Port > 65535 {
 | 
				
			||||||
 | 
							return fmt.Errorf("Port must be between 1 and 65535")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										12
									
								
								flags/parseNumCPUs.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								flags/parseNumCPUs.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					package flags
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "fmt"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (flags *Flags) parseNumCPUs() (err error) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if flags.Vars.NumCPUs <= 0 {
 | 
				
			||||||
 | 
							return fmt.Errorf("Number of CPUs must be greater than 0")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										18
									
								
								flags/parseRole.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								flags/parseRole.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					package flags
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "fmt"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (flags *Flags) parseRole() (err error) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Ensure that role field is not empty
 | 
				
			||||||
 | 
						if flags.Vars.Role == "" {
 | 
				
			||||||
 | 
							return fmt.Errorf("Role cannot be empty")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Ensure that role field is valid
 | 
				
			||||||
 | 
						if flags.Vars.Role != "scheduler" && flags.Vars.Role != "agent" {
 | 
				
			||||||
 | 
							return fmt.Errorf("Role must be either 'scheduler' or 'agent'")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										7
									
								
								flags/types.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								flags/types.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					package flags
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "gitea.ligthert.net/golang/sfcs/vars"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Flags struct {
 | 
				
			||||||
 | 
						Vars *vars.Vars
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										7
									
								
								go.mod
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								go.mod
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					module gitea.ligthert.net/golang/sfcs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					go 1.23.4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require gitea.ligthert.net/golang/sudoku-funpark v0.0.0-20250129164508-c1f2a28ac155
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require github.com/gorilla/websocket v1.5.3
 | 
				
			||||||
							
								
								
									
										4
									
								
								go.sum
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								go.sum
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					gitea.ligthert.net/golang/sudoku-funpark v0.0.0-20250129164508-c1f2a28ac155 h1:o3MLpDn26r/9DOCdATINPck2W0pNdXi6WiJcpKQwAYQ=
 | 
				
			||||||
 | 
					gitea.ligthert.net/golang/sudoku-funpark v0.0.0-20250129164508-c1f2a28ac155/go.mod h1:GdZ2otAB+NMA19Noe7UFeP3gJtHCU4h8N158Oj1jNVY=
 | 
				
			||||||
 | 
					github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
 | 
				
			||||||
 | 
					github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
 | 
				
			||||||
							
								
								
									
										36
									
								
								main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								main.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"gitea.ligthert.net/golang/sfcs/flags"
 | 
				
			||||||
 | 
						"gitea.ligthert.net/golang/sfcs/server"
 | 
				
			||||||
 | 
						"gitea.ligthert.net/golang/sfcs/vars"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func main() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Create a new instance of the Controller struct
 | 
				
			||||||
 | 
						vars := vars.Vars{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Create a new instance of the Flags struct
 | 
				
			||||||
 | 
						flags := flags.Flags{Vars: &vars}
 | 
				
			||||||
 | 
						err := flags.ParseFlags()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							fmt.Println(err)
 | 
				
			||||||
 | 
							os.Exit(1)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Switch on the role
 | 
				
			||||||
 | 
						switch vars.Role {
 | 
				
			||||||
 | 
						case "scheduler":
 | 
				
			||||||
 | 
							server := server.Server{ListenAddress: vars.Address, ListenPort: vars.Port}
 | 
				
			||||||
 | 
							vars.Operator = &server
 | 
				
			||||||
 | 
						case "agent":
 | 
				
			||||||
 | 
							// operator := client.Client{}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						vars.Operator.Start()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										68
									
								
								server/Start.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								server/Start.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
				
			|||||||
 | 
					package server
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"log"
 | 
				
			||||||
 | 
						"net/http"
 | 
				
			||||||
 | 
						"strconv"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/gorilla/websocket"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (server *Server) Start() error {
 | 
				
			||||||
 | 
						// Start the server
 | 
				
			||||||
 | 
						http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 | 
							handleConnections(w, r)
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						log.Fatal(http.ListenAndServe(server.ListenAddress+":"+strconv.Itoa(server.ListenPort), nil))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						time.Sleep(600 * time.Second)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var upgrader = websocket.Upgrader{
 | 
				
			||||||
 | 
						ReadBufferSize:  1024,
 | 
				
			||||||
 | 
						WriteBufferSize: 1024,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func handleConnections(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 | 
						conn, err := upgrader.Upgrade(w, r, nil)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer conn.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						log.Println("Starting server")
 | 
				
			||||||
 | 
						go readMessages(conn)
 | 
				
			||||||
 | 
						writeMessages(conn)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func readMessages(conn *websocket.Conn) {
 | 
				
			||||||
 | 
						for {
 | 
				
			||||||
 | 
							messageType, message, err := conn.ReadMessage()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								log.Println("Error reading message:", err)
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							log.Printf("Received(%d): %s\n", messageType, message)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// This sets the time-out for any incoming messages.
 | 
				
			||||||
 | 
							// conn.SetReadDeadline(time.Now().Add(10 * time.Second))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func writeMessages(conn *websocket.Conn) {
 | 
				
			||||||
 | 
						for {
 | 
				
			||||||
 | 
							err := conn.WriteMessage(websocket.TextMessage, []byte("Hello World!"))
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								log.Println("Error writing message:", err)
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// This sets the time-out for any outgoing messages.
 | 
				
			||||||
 | 
							// conn.SetWriteDeadline(time.Now().Add(10 * time.Second))
 | 
				
			||||||
 | 
							time.Sleep(time.Second)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										6
									
								
								server/types.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								server/types.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					package server
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Server struct {
 | 
				
			||||||
 | 
						ListenAddress string
 | 
				
			||||||
 | 
						ListenPort    int
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										23
									
								
								vars/types.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								vars/types.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
				
			|||||||
 | 
					package vars
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "gitea.ligthert.net/golang/sudoku-funpark/outputter"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Operator interface {
 | 
				
			||||||
 | 
						// Start the operator
 | 
				
			||||||
 | 
						Start() error
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Vars struct {
 | 
				
			||||||
 | 
						// Instance of the Outputter struct
 | 
				
			||||||
 | 
						Outputter *outputter.Outputter
 | 
				
			||||||
 | 
						// Role is either "scheduler" or "agent"
 | 
				
			||||||
 | 
						Role string
 | 
				
			||||||
 | 
						// Operator interface
 | 
				
			||||||
 | 
						Operator Operator
 | 
				
			||||||
 | 
						// [agent] NumCPUs is the number of CPUs to use
 | 
				
			||||||
 | 
						NumCPUs int
 | 
				
			||||||
 | 
						// Address is the address of the instance to listen to/connect to
 | 
				
			||||||
 | 
						Address string
 | 
				
			||||||
 | 
						// Port is the port of the instance to listen on/connect to
 | 
				
			||||||
 | 
						Port int
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user