ccoverstreet / Jablko

Smart Home Interface powered by Go.
MIT License
1 stars 0 forks source link

The next big rewrite #95

Closed ccoverstreet closed 3 years ago

ccoverstreet commented 3 years ago

Is your feature request related to a problem? Please describe.

The current architecture uses mutexes to prevent data within the core of Jablko. These encompass the database tables (users) and the module manager (modmanager). The problem is that managing the state of each means ensuring that mutexes are locked and unlocked correctly the order of requests reflects the order of executed operations.

Describe the solution you'd like

It would be interesting to compare the readability/performance/maintainability of using a single goroutine for each critical resource. For instance, an inbound request would pass a validateRequestTask (that probably contains the *http.Request and a return channel) to a goroutine managing the user database. The user database would then process this request, changing the state of the user/session database as needed. The user database thread would then pass a result back through the return channel (for this case, maybe a bool indicating whether or not the request is allowed to pass). This response would be received by the calling goroutine processing the request.

The user database routine would have a switch statement based on type that determines how the request is processed. This would allow for tasks like user login or validating authentication to be handled separately from database commands such as addUser or deleteUser.

Describe alternatives you've considered

The alternative approach is the current jabko-micro implementation. There is not a pressing need to switch to a new design, but it should be easy to substitute in a new design. All that needs to be kept the same is the API between the dashboard and core and between the core and JMODs. I think the current focus of Jablko development should be fleshing out the expected features and behaviors so that there is a clear goal for the rewrite. I also want to start working on the JMODs themselves so this rewrite will happen in a month or two.

ccoverstreet commented 3 years ago

Who knows, I'll probably find some issue with this new idea. I think the best way of designing Jablko with this method would be to have the database and modmanager as their own goroutine which manages the state of each.

Not sure if having all these different request types will cause a big performance hit. The question is how much request processing should be done outside of the scope of the modmanager. Currently, I think that the http request should not be passed (except for past request) to the modmanager to minimize processing time reading and parsing the body on the modmanager thread. This would limit the performance hit of the single threaded nature of the modmanager. This means that the only change from the current version would be the removal of the locks in modmanager. The order of operations can also be better guaranteed since the requests are processed sequentially in their entirety.

Even if this creates a performance hit, this is a better route for Jablko as guaranteeing that state changes occur in the order that they arrive is critical for maintaining a predictable state. The current method may have out of order execution of intended tasks based on which function receives the modmanager lock first

ccoverstreet commented 3 years ago

On second thought, channels would add a large bottleneck to the program with type checking of tasks

ccoverstreet commented 3 years ago

Channels seem pretty clunky in terms of this structure. The current approach of using sync.RWMutex to maximize throughput seems to work the best.