6 ms·
I've been writing services... as libraries first. Then just wrap the library in a very simple `main()`: ``` #include "servicelib.hpp" int main(int argc, char a
by inetknght 3y ago
I've been writing services... as libraries first. Then just wrap the library in a very simple `main()`:
```
#include "servicelib.hpp"
int main(int argc, char argv)
{
return servicelib{argc, argv}.run();
}
```
The library can be re-used in other apps or services.
Then the whole damn library is unit-testable with any arguments you throw at it. Got an OS where argv may be null? You can unit test that. Got a user who decided to use --iamstupid instead of --iamawesome? You can unit test that too. Want to set up environment variables? Well that's not thread safe, but your test harness can do it before it instantiates the library object.
Want to use semver? You can. I use git commit checksums for versions and automatic tagging to semver. It's more annoying but superawesome.
- agomez314 3y agoCan you give details on how you do “automatic tagging”?
- inetknght 3y agoCI has a step with a bash script which takes the most-recent tag, bumps it to a new semver, and pushes the updated tag pointing to the commit going through CI.
- jampekka 3y agoHundred times this. Nice to hear an odd sound of sanity amisdt the architecture astronaut crowd. YAGNI.
- Joel_Mckay 3y agoWe usually wrap a set of valgrind debugged small test/demo programs that hammer a library to monitor for leaks etc. However, ensuring thread safety can sometimes be a challenge. =)
- inetknght 3y agoWe run unit tests with ASAN. Good test coverage gives us good confidence in safety. I recently picked up a subscription to undo.io and I figure the next time I see any problem then I'll take that for a spin. I've seen trouble with gRPC and trying to debug it is infuriating.
- Joel_Mckay 3y agoI just used AMQP routing to handle loads, and small limited-run programs that cache credentials like netflix biological inspired systems. We were never convinced gRPC could efficiently handle the periodic traffic spike-nature of our data streams (more of n! edges in fault tolerant mode concern). i.e. we run our intake like an insect colony to handle the various architecture roles, and each process instance is only handling a few network links at a time (i.e. gets rid of threading cleanup, busy credential store hits, and error routing.) I wish they used Erlang/Elixir/Phoenix channels to reduce the system complexity, https://dev.to/codecast/how-to-use-phoenix-channels-18k9 https://dev.to/codecast/how-to-use-phoenix-channels-18k9 Sometimes we just need to keep a system running, and quietly replace it with version 2 later... Yet later usually never arrives... lol =)
- giancarlostoro 3y agoUsed to do this in .NET for personal projects then got pulled into various dotnet projects that had their own approaches. But it was really nice. What I had hoped to eventually achieve is being able to hotswap the library somehow so I can have a server with zero downtime for updates, but never found the time to do so. I would assume I would do it via a microservice type of architecture instead.
- capableweb 3y agoYou can just do this with nginx or whatever you have in front (IIS if you're into Microsoft stuff I guess?). Run service at port xxx1, this is your "live" port. When you wanna upgrade, launch service to port xxx2, do graceful reload of config, swap the ports around so "live" port now points to right service, graceful reload of config again and done!
- giancarlostoro 3y agoI should have added I was not doing a web service.
- capableweb 3y agoSo what kind of service were you doing? As far as I know, nginx and others can handle more things than just http.
- swagmoney1606 3y agoIIS makes me want to explode and then die
- neonsunset 3y agoIn .NET for plugin management there are unloadable assemblies so you can dynamically load and unload e.g. plugins at runtime. However, it requires care, has caveats and the industry generally gravitates to other techniques for zero-downtime and/or rolling deployments where the replicas (nodes) are at first drained, then shut down, and replaced one by one or in groups but never in a way where there are none to serve the requests.
- agumonkey 3y agoI wonder if domain modeling crowd doesn't end up doing just this. That said, the lib first approach was made a goal in clojure land, and sometimes it adds some choice/integration fatigue.
- deterministic 3y agoThis is the way.