This article is a basic tutorial on how to setup Hangfire using a dotnet core application.
Before I start rambling, what is Hangfire and what does it do?
Hangfire is an easy way to perform background processing in .NET and .NET Core applications. No Windows Service or separate process are required. It is also backed by persistent storage. It’s great for long running tasks where you have multiple instances of an application and you need or want to start or stop those tasks.
Let’s Start
First we need to choose a database that is compatible with Hangfire. I chose MongoDB because it’s free, but SQL Server is also compatible.
Step 1: Create a docker-compose file
This docker compose will be responsible to create our mongo database. I’ve also added mongo-express to visualize our mongo db on the browser and a beautiful little script runner to create our user with access to the database.
version: '3'
services:
mongo:
image: mongo:3.4.14
container_name: mongo
environment:
- MONGO_INITDB_ROOT_USERNAME=admin
- MONGO_INITDB_ROOT_PASSWORD=admin
ports:
- 27017:27017
restart: unless-stopped
mongo-express:
image: mongo-express
container_name: mongo_express
ports:
- 8081:8081
environment:
ME_CONFIG_MONGODB_ADMINUSERNAME: admin
ME_CONFIG_MONGODB_ADMINPASSWORD: admin
restart: always
mongo-scripts:
image: mongo-scripts
container_name: mongo_scripts
environment:
- SERVER=mongo
- PORT=27017
- DATABASE=HANGFIRE_TUTORIAL
- USERNAME=myuser
- PASSWORD=pwd
build:
context: .
dockerfile: Dockerfile
depends_on:
- mongo
If you are new to docker compose files, you can read about it here.
Step 2: Create a Dockerfile
We will need to create the Dockerfile in the same space of the docker compose file with the following:
FROM mongo:3.4.14
ARG SERVER
ARG PORT
ARG DATABASE
ARG USERNAME
ARG PASSWORD
WORKDIR mongoscripts
COPY . .
RUN tr -d '\r' <run-mongoscripts.sh >run-mongoscripts.sh.tmp && mv -f run-mongoscripts.sh.tmp run-mongoscripts.sh
CMD sh run-mongoscripts.sh ${SERVER} ${PORT} ${DATABASE} ${USERNAME} ${PASSWORD}
This Dockerfile is responsible for copying our bash script and execute it.
Step 3: Create a bash script
The bash script name should be equivalent to the one given in the Dockerfile. The name I gave it was run-mongoscripts.sh and it should be in the same space as the docker compose file.
The bash script should have the following:
#!/bin/sh
main() {
server=$1;
port=$2;
database=$3;
username=$4;
password=$5;
workTime=1;
totalTimes=50;
numberOfChecks=1
while [ $numberOfChecks -le $totalTimes ] &&
! timeout "$workTime" bash -c "echo > /dev/tcp/$server/$port";
do
echo "$server:$port is DOWN after $numberOfChecks check";
sleep $workTime;
numberOfChecks=$(($numberOfChecks + 1));
done;
if ! timeout "$workTime" bash -c "echo > /dev/tcp/$server/$port";
then
echo "$server:$port is DOWN after all checks";
exit 1;
else
echo "$server:$port is UP";
fi
mongo --host $server --port $port admin -u admin -p admin --eval "db.getSiblingDB('$database').createUser({user:'$username',pwd:'$password',roles:[{role:'readWrite',db:'$database'}]})"
}
main "$@";
This script is responsible for creating a user capable of reading and writing in a mongo database of our choosing. It contains a loop for it to wait until the mongodb container is up.
Ok, the worst is over. 😅
Now we can run our docker compose file using this command where the docker compose file is:
docker-compose up -d --build
Go to your browser and you will be able to access mongo-express on http://localhost:8081/.
We finally have our setup complete. 🎉
Step 4: Create a new ASP.NET Core Web API
Open Visual Studio and create a new project using the following templates:
Step 5: Add Hangfire to our project
After our ASP.NET Core Web API has been created, let’s proceed to the installation of Hangfire into our project. Head out to our .csproj and add the following:
<ItemGroup>
<PackageReference Include="Hangfire" Version="1.7.9" />
<PackageReference Include="HangFire.Mongo" Version="0.6.6" />
</ItemGroup>
These are all the packages we are going to need so now we can add our connection string to Mongo DB to feed onto Hangfire.
Step 6: Add MongoDB connection string
Mongo’s template connection string should look like this:
mongodb://<username>:<password>@<host>:<port>/<database>
Let’s add it into appsettings.json
using our settings:
{
...
"ConnectionStrings": {
"HangfireConnection":
"mongodb://myuser:pwd@localhost:27017/HANGFIRE_TUTORIAL"
},
...
}
Step 7: Configure Hangfire
After that we can start to add our dependencies to the Startup.cs file located at the root of the project.
You will have two methods. ConfigureServices and Configure. ConfigureServices is used to add services to the container for them to be available for dependency injection. Configure is where we set up the middlewares that handle every HTTP request.
So, in ConfigureServices we will add our dependency to Hangfire like this:
var options = new MongoStorageOptions
{
MigrationOptions = new MongoMigrationOptions
{
BackupStrategy = MongoBackupStrategy.None,
Strategy = MongoMigrationStrategy.Drop
}
};
services.AddHangfire(x => x.UseMongoStorage(
Configuration.GetConnectionString("HangfireConnection"),
options));
And in Configure we will add this so that we can open the Hangfire Dashboard and to be able to schedule jobs and stop them.
app.UseHangfireDashboard()
.UseHangfireServer();
Awesome. Now we can just run our application and go to /hangfire
and we will be able to see this beautiful dashboard.
We now have our Hangfire configured and ready to go.
Step 8: Add a Job to Hangfire
Our next step will be to add a job to execute every day at 8AM to tell us good morning.
In our Startup.cs file, on the Configure method, we will add this:
RecurringJob.AddOrUpdate<HangfireJobs>(
"GoodMorning",
x => x.GoodMorning(),
Cron.Daily(8));
So, what does this do? This tiny method will add a recurring job to Hangfire that will execute the method GoodMorning
declared on the class HangfireJobs
every day at 8AM identified in the last argument.
Next Step will be to create the class HangfireJobs and its method, GoodMorning.
public class HangfireJobs
{
public void GoodMorning()
{
Console.WriteLine("Good Morning!");
}
}
After this, we can run our app and go to /hangfire/recurring
and see this job waiting for it to be ran. It should look something like this.
Wrap up
This is it. Now you have a functioning application using Hangfire with Mongo DB using Docker where you can add Jobs to run whenever you want and how many times you need.
If you want to follow up on something more, here is some links that may be helpful:
Top comments (0)