Background service in ServiceStack - servicestack

I've got an application w. AppHost (inside Startup.cs) and also a Configure.Db.cs file.
I want to run a background service (Timer based) to routinely do some things, in addition to serving services.
If I add the timer inside Apphost's Configure(), which is run before the Configure.Db, I get into a problem as the background service is dependent on the Db to be configured.
Edit: I just found that it is possible to specify order of Modular startup: https://docs.servicestack.net/modular-startup#modular-startup-prioritization which means I can force the Configure.db to run before Apphost.
Anyway, am I going about this wrong? Should I perhaps have a separate AppHost just for the background job?

I would recommend configuring a Background MQ Service for executing Services in the background.

You can look at how to do this with hangfire by adding the mix
x mix hangfire-postgres
This will allow you to add services that fire in the background on a cron schedule.
To make it work without a database you need to change the postgres provider to the in-memory provider: https://github.com/perrich/Hangfire.MemoryStorage

Related

Is it possible to restart a process in Google Cloud run

We have multiple Google Cloud Run services running for an API. There is one parent service and multiple child services. When the parent service starts it loads a schema from all the children.
Currently there isn't a way to tell the parent process to reload the schema so when a new child is deployed the parent service needs to be restarted to reload the schema.
We understand there there are 1 or more instances of Google Cloud Run running and have ideas on dealing with this, but are wondering if there is a way to restart the parent process at all. Without a way to achieve it, one or more is irrelevant for now. The only way found it by deploying the parent which seems like overkill.
The containers running in google cloud are Alpine Linux with Nodejs, running an express application/middleware. I can stop the node application running but not restart it. If I stop the service Google Cloud Run may still continue to serve traffic to that instances causing errors.
Perhaps I can stop the express service so Google Cloud run will replace that instance? Is this a possibility? Is there a graceful way to do it so it tries to complete and current requests first (not simply kill express)?
Looking for any approaches to force Google Cloud Run to restart or start new instances. Thoughts?
Your design seems, at high level, be a cache system: The parent service get the data from the child service and cache the data.
Therefore, you have all the difficulties of cache management, especially cache invalidation. There is no easy solution for that, but my recommendation will be to use memorystore where all child service publish the latest version number of their schema (at container startup for example). Then, the parent service checks (at each requests, for example) the status in memory store (single digit ms latency) if a new version is available of not. If a new, request the child service, and update the parent service schema cache.
If applicable, you can also set a TTL on your cache and reload it every minute for example.
EDIT 1
If I focus only on Cloud Run, you can in only one condition, restart your container without deploying a new version: set the max-instance param to 1, and implement an exit endpoint (simply do os.exit() or similar in your code)
Ok, you loose all the scale up capacity, but it's the only case where, with a special exit endpoint, you can exit the container and force Cloud Run to reload it at the next request.
If you have more than 1 instance, you won't be able to restart all the running instances but only this one which handle the "exit" request.
Therefore, the only one solution is to deploy a new revision (simply deploy, without code/config change)

How ConfigCat webhooks would work in application running behind load balancer?

There are 4 instances of an application running behind a load balancer. How the ConfigCat webhook would work in this case? Do we need to configure 4 public URL's for all 4 servers in webhook settings?
Could you share some details about your use case? What would you like to achieve with webhooks? What kind of SDK are you using? What is the polling mode?
If you want to refresh the SDK's cache on Feature Flag value changes, you should consider using a distributed cache implementation (e.g. redis). Example custom cache in Java: https://configcat.com/docs/sdk-reference/java#custom-cache
If you implement a custom distributed cache, you'll only need to add your load balancer's url to the webhook because refreshing the cache in one instance will refresh the cache in the distributed cache so all of your instances could work with the latest configurations.
If you want to get notified about changes in each applications, there are different possibilities:
You can configure 4 public urls and use the webhooks just like you mentioned it.
If you are using auto polling mode, you can skip the webhooks part and start using the SDK's built-in configuration changed callbacks. e.g. in java: configurationChangeListener part at https://configcat.com/docs/sdk-reference/java#auto-polling-default. When the auto poll mode's polling happens the SDK detects if the configuration changed and it fires this event.
If you could share more details I could help you more.
Disclaimer: I am one of the founders of ConfigCat.

How do I handle multiple apps running on a single server?

I am new to Chef. I just finished creating a cookbook that deploys a node.js app, configures Nginx, and then starts the app as 1 or more workers that are "load balanced" by Nginx. It works great. I made sure to keep it pretty generic, and all the app level config is done via attributes.
Now I am trying to think about an instance where I have multiple node.js apps running on the same server. For example, the primary API app, and another app that registered itself as a Gearman worker.
How would I go about doing this? Would I simply create another cookbook that is specific to that app, make sure it includes the generic cookbook's recipe, and then do attribute overrides just for that app's recipe?
Or, would it be better if I moved away from using attributes for the app config, and used data_bags instead?
Any help is appreciated.
I would have separated nginx and node.js installation/configuration into separate cookbooks.
If you must have several different applications running on node.js, I think it's ok to add a recipe for every application inside node.js cookbook and make sure each of them includes installation of node.js itself.
If you must have several instances of 1 and the same application/service running, then it is better to use one recipe with different attributes or data bags to introduce differences among instances.
Any more specific questions?
You should use roles Roles to manage multiple cookbooks on a server.
I'm not exactly sure of your scenario, but from your description, I would create 3 cookbooks. One that installs nginx, one that installs your app, and one that does node specific configuration and deployment. Bundle these into a role 'app_server' and put the role in the run_list.
This makes your app more composable, and it's easier to change out any of the pieces in the future.

Run Windows Program While Not Logged In

I've recently become "reacquainted" with Windows and I'm also new to .NET & C#. I'm trying to figure out a way to run a program on a Windows 2003 machine at all times (i.e. it runs when no one is logged in and automatically starts on server boot). I think I'm overcomplicating the problem and getting myself stuck.
This program, called Job.exe, normally runs in a GUI, but I do have the option of running it from the command line with parameters.
Because of the "always on" part, the first thing that comes to mind is to create a service. Ridiculously, I'm getting stuck on how exactly to run the executable (Job.exe) from within my Service1.cs file (did I mention I'm new to c#?).
A couple other points I'm stuck on regarding creating a service are how/where to configure desktop interaction since I want Job.exe to run totally in the background. Also, since OnStart is supposed to return to the OS when finished, I'm a little confused as to where I should put the code to execute the program; do I place it in my OnStart method or create a method that I then call from OnStart?
Last question on creating a service is about the parameters. Job.exe accepts two parameters in total, one static and one dynamic (i.e. could be defined via the service properties dialog in the services management console). I'd like to be able to create multiple instances of the service specifying a different dynamic parameter for each one. Also, the dynamic parameter should be able to accept a string array.
I'm sure there are options outside of creating a service, so I will take any and all suggestions.
Since you mentioned that you may be over-complicating the problem, you may consider using the Task Scheduler to run your application.
Using the Task Scheduler will allow you to make a "regular" desktop application which is arguably a simpler approach than creating your own service. Also, the Task Scheduler has many options that fit the requirements you touched on.
The simplest approach might be to create a service, reference the application's assembly, and call it's Main() method to start the application. The application itself could use Environment.UserInteractive to detect if it is running as a service or as a desktop application.
One thing to watch out for, as you mention, is that the Start method of a service (and the other control methods) is expected to return immediately-ish (in the timespan of the "Starting Service..." dialog) so you'll need to spin up a thread to run the main method. Something like this:
Thread t = new Thread(() => { MyApplication.Application.Main("firstParam", "secondParam"); });
t.Start();
The params could come from a file and the service can be configured with the file name as a parameter (see this article for one of many examples on how to do that), or the service could be configured as you mentioned to take the parameters and pass them along to the application's main method. These are both viable approaches. Either way, only one instance of a service can be running at a time, so you'd need to register the service multiple times with different names to configure different parameters.

Codeigniter CLI As Daemon

I am creating a queue system where I need a set of workers to run jobs. For the queue I am planning on using Amazon's SQS. For my workers I would like to run instances of Codeigniter because the core application will also use Codeigniter and I would like to share the models of the workers with that of the core application.
I see that it is possible to hit a controller method using CI's CLI (http://codeigniter.com/user_guide/general/cli.html). However, these workers should continually run, unless I kill them. I have looked into this article about setting up daemons using php: http://kevin.vanzonneveld.net/techblog/article/create_daemons_in_php/ This method requires that I use this class: https://github.com/kvz/system_daemon.
I am not sure if I should be calling and running System Daemon inside my controller in CI to spawn the entire CI instance as a daemon? Or is there a command-line approach where I can establish my call to the CI method as a daemon and then avoid using the 'System Daemon' class altogether? Any considerations I should be aware of? I have never created a running daemon, I have only used the cron tab to restart processes but that will not work in my case.
I dont know if anyone has daemonized properly codeigniter (I read that many had tried).
I had a similar situation with yours and I ended up using the System Daemon class which constantly checks SQS and then calling a CLI codeigniter via system() passing the message as a parameter.
My approach works for ~10 months without having any issues and serves ~30-40k messages per day.

Resources