# sfcs
Sudoku-Funpark Cluster Software: same as [Sudoku-funpark](https://gitea.ligthert.net/golang/sudoku-funpark/), but networked.

## Notes

### Network Protocol
While network and transport is done via WebSocket, traffic is sent using Python.
( 🤔 not sure if this is the smartest idea, as Golang isn't really that strong with JSON. 🫠 )

Agent => Manager:
- register: register an agent with the manager
- update: agents sends CPU and Mem metrics (does this every second)
- solution: solution of a task given by the manager
- deregister: deregister an agent from the manager

Manager => Agent:
- task: A task for the agent to chew on

### Commands

#### Register
1. Hostname
2. CPU cores
3. Memory

#### Update
1. cpu usage
2. memory usage
3. assigned task [none,taskID]

#### Solution
1. taskId
2. solution ([][9]string)

#### deregister
1. Hostname

#### task
1. taskId
2. split
3. part
4. puzzle ([][9]string)


### Protocol
For ease of programming I would like start of easy and use `;`-separated string to push values between manager and its agents. In this setup the format is predefined, and parsing will be based on the first field after the string is split on `;`.

* register;string;int;memory int
* update;float;float;int
* solution;string;string;string;string;string;string;string;string;string;string
* deregister;string
* task;int;int;int;string;string;string;string;string;string;string;string;string

I still have the impression that Go and JSON is hard to do as the rigidness of Go does not go well with the free spirited nature of JSON. I might revise this in the future.

### Imports
I intend use `golang/sudoku-funpark` for the code to determine workload and calculate the puzzles that need to be solved. And while this is all modular, it unfortunately isn't flexible enough to actually use it in the tool (or I am not trying hard enough).

### Other notes
#### Load ordering
Outputter
Controller
Export
Flags
Solver

```Go
	controller := controller.Controller{}
	outp := outputter.Outputter{}
	export := export.Export{Controller: &controller}
	flags := flags.Flags{Controller: &controller}
	solver := solver.Solver{Controller: &controller, Outp: &outp}
```
### Manager & Agent channel setup
Both the manager and the agent will have similar setups:
* `*websocket.Conn` is stored in _types.go_.
* Any go routine can write to the socket.
* All reads go to a `readProcessor()` which in turn parses the message, and in turn does the appropriate logic (read, calling go routine/functions)

This does however presents me with a problem. Since all communication is reactive, state-less, and all over the same connection; so tracking things is a bit hard. And this is something for maybe the next phase. So for now, reactive content only. This said, I need figure out how on earth I can prevent an agent from taking two jobs at the same time. I guess I will need to build in some agent state tracking for this.

#### Server setup
_(This piece assumes that the network is super fast, and turbo stable.)_

The current setup of the server is only the thing that its connected to. There is a writer that spams something, a reader that prints everything it receives to the console. And that is it. Pretty much split-brain and it currently lacks the ability to manage workloads on agents.

For this exercise it needs to be able to handle multiple agents, but start at one. There needs to be an interface that should tell me how much CPU/MEMs an agent has. And finally tell the agent to solve something and accept any answers it returns.

Another issue is that it needs a manager interfaces to keep track of Agents, agents metrics, status. But also allow users to issue commands. NFC how I am going to do that. But something tells me it will require me to find a way to communicate all this with the user, and I can do this with a simple REST API, or create a terminal interface, or do web things.


1. Incoming connection gets caught by `handleConnections()`
2. `handleConnections()` verifies an agent registers
3. After registeration it puts this into a map, along with the `conn` and stuffs this into a slice of maps
4. The manager pics up the new agent, and offers info to anyone who wants to see it.
5. A client can ask the manager to solve a puzzle, manager calculates which agents to use, sends of the work.
6. Solution is returned and stored.

So from there.

I think the biggest issue now is find a way to have a terminal or web interface with the user.
