How to insert data at initialisation of nodejs express application - node.js

I would also like that on multiple runs the data is not stacked multiple times.
I have done this once with spring boot's CommandLineRunner:
#SpringBootApplication
public class HamstergotchiApplication {
public static void main(String[] args) {
SpringApplication.run(HamstergotchiApplication.class, args);
}
/**
* Add challenges on startup if there are no challenges in the database.
* This will be run at startup.
*/
#Bean
public CommandLineRunner initializeDB(ChallengeRepository challengeRepository){
return (args)->{
// Add default challenges if the DB is empty
if(challengeRepository.count() == 0) {
challengeRepository.save(new Challenge(0, ChallengeType.GEEN_ALCOHOL, false));
challengeRepository.save(new Challenge(0, ChallengeType.MINDER_FRISDRANK_MET_SUIKER, true));
challengeRepository.save(new Challenge(0, ChallengeType.GROENTE_EN_FRUIT_20_PROCENT, false));
challengeRepository.save(new Challenge(0, ChallengeType.GEEN_VLEES, true);
}
};
}
}

You might want a separate script/command to initialize the database.
If you don't want that, well, just something like
async function initializeDatabase() {
if(databaseContainsEntries()) return;
addEntry(...);
addEntry(...);
addEntry(...);
addEntry(...);
}
async function boot() {
await initializeDatabase();
app.listen(...);
}
boot();
instead of a vanilla
app.listen(...);

Related

Spring boot multithreaded async not working

The task is to call a database, retrieve certain records update and save them.
As the amount of records if fairly large we want to do this Async, however, this doesn't seem to be implemented correctly.
The main class:
#SpringBootApplication
#EnableAsync
MainApplication() {
#Bean("threadPoolExecutor")
public TaskExecutor getAsyncExecutor(){
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(DataSourceConfig.getTHREAD_POOL_SIZE());
executor.setMaxPoolSize(DataSourceConfig.getTHREAD_POOL_SIZE());
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setThreadNamePrefix("RetryEnhancement-");
return executor;
}
}
Method in the first service:
#Service
public class FirstService() {
#Transactional
public void fullProcess() {
for(int counter = 0; counter < ConfigFile.getTHREADS(); counter++){
secondaryService.threads();
}
}
}
Method in the second service:
#Service
public class SecondService () {
#Async("threadPoolExecutor")
public void threads() {
while(thirdService.threadMethod()) {
//doNothing
}
}
}
Method in the third service:
#Service
public class ThirdService() {
#Transactional
public boolean threads() {
Record record = repository.fetchRecord();
if(record!=null) {
updateRecord(record);
saveRecord(record);
return true;
} else {
return false;
}
}
}
Repository:
public interface repository extends CrudRepository<Record, long> {
#Lock(LockModeType.PESSIMISTIC_WRITE)
Record fetchRecord();
}
The issue I'm finding is that, while the code executes perfectly fine, it seems to have a Synchronous execution (found by adding a .sleep and watching the execution in the logger).
The seperate threads seem to be waiting until the other is executed.
I'm probably doing something wrong and if another thread already explains the issue, than please refer it, though I have not been able to find this issue in a different thread.
Your solution is way to complex. Ditch all of that and just inject the TaskExecutor and do the updateRecord in a separate thread (you might need to retrieve it again as you are now using a different thread and thus connection.
Something like this should do the trick
private final TaskExecutor executor; // injected through constructor
public void process() {
Stream<Record> records = repository.fetchRecords(); // Using a stream gives you a lazy cursor!
records.forEach(this::processRecord);
}
private void processRecord(Record record) {
executor.submit({
updateRecord(record);
saveRecord(record);
});
}
You might want to put the processRecord into another object and make it #Transactional or wrap it in a TransactionTemplate to get that behavior.

Autofac interceptor not working for some classes

I have to do some extra logic layer on existing classes. I'm using autofac.
The project is Windows service having also Kestrel server. Program.cs e.g.
void Main(string[] args) {
var customQueue = new CustomQueue();
var someClass = new SomeClass(customQueue);
var randomClass = new RandomClass();
// do some logic here with using declared instances
var server = new Server(someClass, randomClass);
server.Start();
}
And here is the Server.cs
class Server {
private IWebHost _host;
public Server(SomeClass cls, RandomClass cls1) {
// set to fields
}
void Start() {
_host = new WebHostBuilder()
.UseKestrel()
.ConfigureServices(services =>
{
services.AddAutoFac(); // first as per doc in order to scaffold 'ConfigureContainer'?
services.AddSingleton(someClass); // fields
services.AddSingleton(randomClass); // fields
})
.UseContentRoot(Directory.GetCurrentDirectory())
.ConfigureAppConfiguration(...)
.ConfigureLogging(...);
.UseStartup<Startuo>()
.Build();
_host.StartAsync();
}
}
Startup.cs
public class Startup
{
public ILifetimeScope AutofacContainer { get; private set; }
public IServiceProvider ConfigureServices(IServiceCollection services)
{
// create a container-builder and register dependencies
var builder = new ContainerBuilder();
// populate the service-descriptors added to `IServiceCollection`
// BEFORE you add things to Autofac so that the Autofac
// registrations can override stuff in the `IServiceCollection`
// as needed
builder.Populate(services);
builder.RegisterType<SomeClass>()
.As<ISomeClass>()
.EnableInterfaceInterceptors()
.InterceptedBy(typeof(SomeClassInterceptor));
builder.Register(_ => new SomeClassInterceptor());
AutofacContainer = builder.Build();
return new AutofacServiceProvider(AutofacContainer);
}
}
And last SomeClassInterceptor.cs
public class SomeClassInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
try
{
invocation.Proceed();
if (invocation.ReturnValue is Task taskResult)
{
taskResult.ContinueWith(
t =>
{
Console.WriteLine("OOHH YEAHH");
}, TaskContinuationOptions.None);
}
else
{
Console.WriteLine("WOW");
}
}
catch (Exception ex)
{
Console.WriteLine("EXCEPTIOOOOOOOOOOOOONNNNNNNNNNNNNNNNNNNN");
}
}
}
I've tried with Named and Typed registration with having Intercept(...) attribute but still no success. Nothing gets triggered.
Also ISomeClass is inheriting other interfaces, I've tried setting .As<>() also with those but no.
What am I missing?
In order to let the interceptor works. The class should be build by Autofac.
services.AddAutofac();
services.AddSingleton(someClass);
services.AddSingleton(randomClass);
In your case you configure Autofac using the AddAutofac method then add SomeClass as a singleton using the AddSingleton which will override the Autofac configuration. There is no way that Autofac can inject the interceptor in it.
If you want to register SomeClass as singleton you should register it using the SingleInstance() method
builder.RegisterType<SomeClass>()
.As<ISomeClass>()
.SingleInstance()
.EnableInterfaceInterceptors()
.InterceptedBy(typeof(SomeClassInterceptor));

How do I replace Asynctask with RxJava Observer?

I have a test project with Room database. Using Asynctask I can successfully insert an object with some test data into the database. I'm trying to learn RxJava and replace Asynctask with RxJava's observer, but it doesn't work. I have read alot of documentation and watched tutorials, but I don't think I quite get it. Here's the relevant code:
Here I set my Room object with the data from my List:
for(ObjectForArray item: listToDatabase) {
myRoomEntity.setName( item.getName() );
Log.d( "TAG", myRoomEntity.getName() );
}
Then I try to use RxJava Observable to insert data into the database. This was originally and successfully done using Asynctask:
Observable<MyRoomEntity> myRX = Observable
.just(myRoomEntity)
.subscribeOn( Schedulers.io() )
.observeOn( AndroidSchedulers.mainThread() );
myRX.subscribe( new Observer<MyRoomEntity>() {
#Override
public void onSubscribe(Disposable d) {
Log.d("TAG ONSUBSCRIBE", d.toString());
try {
myViewModel.insertDatabase( myRoomEntity );
Log.d( "TAG", "Populating database Success" );
}catch(Error error) {
Log.d( "TAG", error.toString() );
}
}
The OnNext, OnError and OnComplete are empty.
When I run the project it crashes with the error:
Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
I'm obviously using RxJava wrong since the point is to do asynchronous tasks away from the main thread.
i have use RX java in replace of Asyntask as it has been deprecated in android 9
there are multiple replacements that android provides like Executors, threads, Listenable Futures , Coroutines 🔥, so you are looking how to implement this with rxjava and how RX Java java helps your to migrate just add these dependencies first in gradle
implementation "io.reactivex.rxjava2:rxjava:2.2.20"
implementation "io.reactivex.rxjava2:rxandroid:2.1.1"
once you import lets start working with RX java i will let you know where you can put background task, pre execute, on post execute like asynctask
lets start codding with Rx java first , i have comment in the method that will help you to put the code
Observable.fromCallable(new Callable<Boolean>() {
#Override
public Boolean call() throws Exception {
/// here is your background task
return true;
}
}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Boolean>() {
#Override
public void onSubscribe(Disposable d) {
//// pre execute here is my progress dialog
showProgressDialog(getString(R.string.scanning));
}
#Override
public void onNext(Boolean aBoolean) {
//// here is on sucess you can do anystuff here like
if (aBoolean){
/// if its value true you can go ahead with this
}
}
#Override
public void onError(Throwable e) {
/// this helps you to go if there is any error show dialog whatever you wants here
Log.e("error of kind",e.getMessage() );
}
#Override
public void onComplete() {
/// when your task done means post execute
}
});
once its done lets start working with implementation
Observable.fromCallable(new Callable<Boolean>() {
#Override
public Boolean call() throws Exception {
/// here is your background task
uribitmap = getScannedBitmap(original, points);
uri = Utils.getUri(getActivity(), uribitmap);
scanner.onScanFinish(uri);
return true;
}
}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Boolean>() {
#Override
public void onSubscribe(Disposable d) {
//// pre execute here is my progress dialog
showProgressDialog(getString(R.string.scanning));
}
#Override
public void onNext(Boolean aBoolean) {
//// here is on sucess you can do anystuff here like
if (aBoolean){
/// if its value true you can go ahead with this
}
}
#Override
public void onError(Throwable e) {
/// this helps you to go if there is any error show dialog whatever you wants here
Log.e("error of kind",e.getMessage() );
}
#Override
public void onComplete() {
/// when your task done means post execute
uribitmap.recycle();
dismissDialog();
}
});
now i will do this with executors :
/// pre execute you can trigger to progress dialog
showProgressDialog(getString(R.string.scanning));
ExecutorService executors = Executors.newSingleThreadExecutor();
executors.execute(new Runnable() {
#Override
public void run() {
//// do background heavy task here
final Bitmap uribitmap = getScannedBitmap(original, points);
uri = Utils.getUri(getActivity(), uribitmap);
scanner.onScanFinish(uri);
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
//// Ui thread work like
uribitmap.recycle();
dismissDialog();
}
});
}
});
You are getting this error because you are trying to insert an Object on the main (UI) thread.
You should do something like this:
Observable.fromCallable(() -> myViewModel.insertDatabase( myRoomEntity ))
.subscribeOn( Schedulers.io() )
.observeOn( AndroidSchedulers.mainThread() );
And then use an Observer to subscribe to the Observable.
Please try restructuring your code like this:
Completable.fromAction(() -> myViewModel.insertDatabase(myRoomEntity))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(() -> Log.d("TAG", "Populating database Success"),
throwable -> Log.d("TAG", throwable.toString()))
Considerations:
If your myRoomEntity is not available before this whole construct gets subscribed, make sure you use defer http://reactivex.io/documentation/operators/defer.html
Your subscribe section handlers are operating on "main", that's why you were receiving a crash.
If possible, avoid unnecessary just calls

Why is my AppFunc called twice for each owin request?

I have this simple self hosted "Hello World" app which I doesn't understand how it works 100 %.
namespace HelloOwin
{
using System;
using Microsoft.Owin.Hosting;
using Owin;
using AppFunc = System.Func<System.Collections.Generic.IDictionary<string, object>, System.Threading.Tasks.Task>;
class Program
{
static void Main(string[] args)
{
using(WebApp.Start<Startup>(url: "http://localhost:9765/"))
{
Console.ReadLine();
}
}
}
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.Run(context =>
{
var task = context.Response.WriteAsync("Hello world!");
return task;
});
}
}
}
For each request I'm doing to this application the Func defined in app.Run is run twice, why so?
Preinitialization calls means just some code that you want to be executed before you call configureapp in the startup. you can do some operation that requires this or some logging really depends on your requirements.

Playframework Excel file generation

I've installed excel module in order to generate reports from datas recorded by my application into database.
It works fine : i can create report simply by clicking on a link into my main page and render into excel template.
But i'd rather generate excel file periodically (using a job) and save it into a shared folder, and that without any human action (so not by clicking on a link).
It's like I want to trigger the associated controller to render into my template automatically.
Does anyone got any tips on it for me?
So the problem is you can't pass some parameters into the job, or...?
Using something like this just doesn't work?
#On("0 45 4-23 ? * MON-FRI")
public class ExcelJob extends Job {
public void doJob() {
// generate excel
}
}
I wrote my own Excel generator using JExcel, and I use it for scheduled generation without a problem. It also doesn't require a template, because the report structure is derived from annotations. This is roughly 20 lines of code - you may want to try it for yourself.
This is really rough and lacks good user feedback, but gives you the idea...
Excel generator - not Play-specific in any way
public class ExcelGenerator
{
public void generateReport(Function successCallback,
Function failureCallback)
{
try
{
byte[] report = // generate your report somehow
successCallback.execute(report);
}
catch (Exception e)
{
failureCallback.execute(e.getMessage());
}
}
}
A function interface for callbacks (very basic)
public interface Function
{
public void execute(Object... args);
}
Your Play controller
public class MyController extends Controller
{
public static void index()
{
render();
}
public static void createReport()
{
Function failureCallback = new Function()
{
public void execute(Object... args)
{
flash.error(args[0]);
indxe();
}
};
Function successCallback = new Function()
{
public void execute(Object... args)
{
renderBinary((byte[])args[0]);
}
};
ExcelGenerator excelGenerator = new ExcelGenerator();
excelGenerator.generateReport(successCallback,
failureCallback);
}
}
Finally, re-use the ExcelGenerator from your job
public class MyJob extends Job
{
public void doJob()
{
Function failureCallback = new Function()
{
public void execute(Object... args)
{
Logger.error(args[0]);
}
}
Function successCallback = new Function()
{
public void execute(Object... args)
{
byte[] report = (byte[])args[0];
// write report to disk
}
}
ExcelGenerator excelGenerator = new ExcelGenerator();
excelGenerator.generateReport(successCallback,
failureCallback);
}
}
You'll still need to write your own report generator, or refactor the existing excel module to provide what you need.
So if you want to run and manage several jobs you can do something like this
for (int i = 0; i < 10; i++) {
SendingMessageJob sendingMessageJob = new SendingMessageJob();
promises.add(sendingMessageJob.now());
}
boolean allDone = false;
while (!allDone) {
allDone = true;
for (F.Promise promise : promises) {
if (!promise.isDone()) {
allDone = false;
break;
}
}
}
// when arrive here all jobs have finished their process
You can check the Play documentation, specifically the section on jobs, where you'll see examples on how to create automatically triggered methods. This should solve your issue.
EDIT (update on comment):
You can manually trigger a job, do this:
new MyExcelGeneratorJob().doJob();
Thing is, Play is stateless, so the job should use data from the database. Instead of trying to pass parameters from your request into the Job (won't work) try to store that data in a staging area in the database that the job loads and processes to generate the excel.

Resources