How to gracefully end test client - java

I have a simple cumulocity test client. The code runs fine but the jvm does not stop when the code finishes.
Some threads are still running: MultiThreadedHttpConnectionManager.
How to gracefully shutdown the open connections allocated by:
InventoryApi inventory = platform.getInventoryApi() ?
_
...
platform = new PlatformImpl(App.C8Y_URL, new CumulocityCredentials(App.C8Y_USER, App.C8Y_PWD));
InventoryApi inventory = platform.getInventoryApi();
GId testId = new GId("123456");
ManagedObjectRepresentation testDevice = inventory.get(testId);
MeasurementApi mApi = platform.getMeasurementApi();
MeasurementRepresentation measurement = new MeasurementRepresentation();
measurement.setType("c8y_SampleRate");
measurement.setSource(testDevice);
DateTime time = new DateTime();
System.out.println("time " + time.toString());
measurement.setDateTime(time);
Map<String, Object> flowRateFragment = App.createFlowRateFragment(new BigDecimal(20.5));
measurement.set(flowRateFragment, "c8y_SampleRate");
MeasurementRepresentation measurementCreation = mApi.create(measurement);
...

To gracefully shutdown your Cumulocity client call platform.close().

NO you cannot exit after the code finished. Cumulocity agent is made to run continuously so, they won't stop the thread.
If you want out exit then you have use
System.exit(0); //Change the status code accordingly.

Related

Is there a way to tell what Carrier Thread a Virtual Thread is running on?

I am playing around with Project Loom for the first time and I have some code
try (var executor = Executors.newVirtualThreadExecutor()) {
IntStream.range(0, 16).forEach(i -> {
System.out.println("i = " + i + ", Thread ID = " + Thread.currentThread());
executor.submit(() -> {
System.out.println("Thread ID = " + Thread.currentThread());
});
});
}
with output like
Thread ID = VirtualThread[#37]/runnable#ForkJoinPool-1-worker-4
Thread ID = VirtualThread[#33]/runnable#ForkJoinPool-1-worker-5
i = 9, Thread ID = Thread[#1,main,5,main]
Thread ID = VirtualThread[#43]/runnable#ForkJoinPool-1-worker-9
Thread ID = VirtualThread[#46]/runnable#ForkJoinPool-1-worker-11
i = 10, Thread ID = Thread[#1,main,5,main]
i = 11, Thread ID = Thread[#1,main,5,main]
Is there a way I can tell what Carrier Thread each Virtual Thread is running on?
Does ForkJoinPool-1-worker-11 represent a particular Carrier (Platform) Thread, or does it mean something else?
Yes, this suffix is the name of the current carrier thread.
When I use the following code
public static void main(String[] args) throws InterruptedException {
Set<String> threadStrings = ConcurrentHashMap.newKeySet();
try(var executor = Executors.newVirtualThreadPerTaskExecutor()) {
executor.invokeAll(Collections.nCopies(16,
() -> threadStrings.add(Thread.currentThread().toString())));
}
System.out.println("\tSimple Run");
threadStrings.stream().sorted().forEachOrdered(System.out::println);
threadStrings.clear();
try(var executor = Executors.newVirtualThreadPerTaskExecutor()) {
executor.invokeAll(Collections.nCopies(16, () -> {
threadStrings.add(Thread.currentThread().toString());
Thread.sleep(100);
return threadStrings.add(Thread.currentThread().toString());
}));
}
System.out.println("\tWith wait");
threadStrings.stream().sorted().forEachOrdered(System.out::println);
}
It prints
Simple Run
VirtualThread[#15]/runnable#ForkJoinPool-1-worker-1
VirtualThread[#17]/runnable#ForkJoinPool-1-worker-2
VirtualThread[#18]/runnable#ForkJoinPool-1-worker-3
VirtualThread[#19]/runnable#ForkJoinPool-1-worker-4
VirtualThread[#20]/runnable#ForkJoinPool-1-worker-1
VirtualThread[#21]/runnable#ForkJoinPool-1-worker-1
VirtualThread[#22]/runnable#ForkJoinPool-1-worker-4
VirtualThread[#23]/runnable#ForkJoinPool-1-worker-1
VirtualThread[#24]/runnable#ForkJoinPool-1-worker-4
VirtualThread[#25]/runnable#ForkJoinPool-1-worker-4
VirtualThread[#26]/runnable#ForkJoinPool-1-worker-1
VirtualThread[#27]/runnable#ForkJoinPool-1-worker-4
VirtualThread[#28]/runnable#ForkJoinPool-1-worker-4
VirtualThread[#29]/runnable#ForkJoinPool-1-worker-1
VirtualThread[#30]/runnable#ForkJoinPool-1-worker-4
VirtualThread[#31]/runnable#ForkJoinPool-1-worker-4
With wait
VirtualThread[#36]/runnable#ForkJoinPool-1-worker-2
VirtualThread[#37]/runnable#ForkJoinPool-1-worker-3
VirtualThread[#37]/runnable#ForkJoinPool-1-worker-8
VirtualThread[#38]/runnable#ForkJoinPool-1-worker-4
VirtualThread[#38]/runnable#ForkJoinPool-1-worker-8
VirtualThread[#39]/runnable#ForkJoinPool-1-worker-1
VirtualThread[#39]/runnable#ForkJoinPool-1-worker-8
VirtualThread[#40]/runnable#ForkJoinPool-1-worker-5
VirtualThread[#40]/runnable#ForkJoinPool-1-worker-8
VirtualThread[#41]/runnable#ForkJoinPool-1-worker-6
VirtualThread[#41]/runnable#ForkJoinPool-1-worker-8
VirtualThread[#42]/runnable#ForkJoinPool-1-worker-7
VirtualThread[#42]/runnable#ForkJoinPool-1-worker-8
VirtualThread[#43]/runnable#ForkJoinPool-1-worker-5
VirtualThread[#43]/runnable#ForkJoinPool-1-worker-8
VirtualThread[#44]/runnable#ForkJoinPool-1-worker-1
VirtualThread[#44]/runnable#ForkJoinPool-1-worker-8
VirtualThread[#45]/runnable#ForkJoinPool-1-worker-5
VirtualThread[#45]/runnable#ForkJoinPool-1-worker-6
VirtualThread[#46]/runnable#ForkJoinPool-1-worker-5
VirtualThread[#46]/runnable#ForkJoinPool-1-worker-8
VirtualThread[#47]/runnable#ForkJoinPool-1-worker-2
VirtualThread[#49]/runnable#ForkJoinPool-1-worker-1
VirtualThread[#49]/runnable#ForkJoinPool-1-worker-8
VirtualThread[#50]/runnable#ForkJoinPool-1-worker-2
VirtualThread[#50]/runnable#ForkJoinPool-1-worker-6
VirtualThread[#51]/runnable#ForkJoinPool-1-worker-3
VirtualThread[#51]/runnable#ForkJoinPool-1-worker-5
VirtualThread[#52]/runnable#ForkJoinPool-1-worker-2
VirtualThread[#52]/runnable#ForkJoinPool-1-worker-8
(results may vary)
demonstrating how the carrier thread might change when performing a sleep. But in the current snapshot (“build 18-loom+6-282”) it’s not possible to specify your own Executor anymore and there is no method for querying the virtual thread about the carrier thread it uses (other than the implicit hint via toString()). So, the management of the underlying host threads is mostly a black box in this version.
Keep in mind that this is an ongoing development. It’s not clear whether and how this will change.

Problem with Androids "OneTimeWorker", it executes when app starts

Short description:
I am currently working in Android Studio with OneTimeWorkRequest(). What I want to achieve is to create a background-worker that runs and repeats "almost" on a specific time, like every hour (09:00, 10:00, etc). It has not to be exactly but should not variate too much after a long time running.
I already know that the worker only runs every 15 minutes at minimum due to the android restrictions (like battery saving mechanism and so on). I do not need the worker to run exactly at the given time but at least almost around a target time! That is why I used OneTimeWorkRequest() instead of PeriodicWorkRequest() because I needed the possibility of variation in setting the intervall for the worker since the documentation mentions that the PeriodicWorkRequest() will add up a time delay from one execution to another.
What I did:
I have created a custom Worker-Class and used OneTimeWorkRequest() in my MainActivity to create the BackgroundWorker. I have set the setInitialDelay() of the worker to 20 minutes for testing purpose. Everytime the worker did doWork() it creates another OneTimeWorkRequest() at the end of execution so a chain of worker gets created in at a given time. The worker gets queued with the enqueueUniqueWork() method from the WorkerManager.getInstance(context) and the intervall is calculated.
The Problem:
Everytime I close the App's process and reopen the App, the Worker executes directly. Also when I list all worker created by the specified Tag, it lists many workers. It seems to me that my logic created too many worker without closing the old ones, or it creates multiple ones? Yet I thought the enqueueUniqueWork() would replace or create only unique/single worker with the given tag... In addition the WorkManager.getInstance(this).cancelAllWorkByTag(TAG) function does not close the (later in this post) listed worker!
Right now it is not important for me how to create worker execution at a given time but how to create consistent Worker-Chain with OneTimeWorkRequest() that do not create a "worker-overload", if possible. Yet I am open for alternative solutions.
So again:
Why does the worker execute after closing the process and opening the App?
Why are there so many workers listed?
Does my logic create one single worker chain or multiple ones?
Is my logic even consistent/usable like this?
Why are the worker not closing using .cancelAllWorkByTag(TAG)?
Code:
// MainActivity.java:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
// For testing purpose used...
ListScheduledWorker(TAG);
WorkManager.getInstance(this).cancelAllWorkByTag(TAG);
ListScheduledWorker(TAG);
// ...until here.
CreateOneTimeWorker();
...
}
private void CreateOneTimeWorker(){
long timeValue = 20;
TimeUnit timeUnit = TimeUnit.MINUTES;
String workerTag = MhdExpirationPushNotification.class.getSimpleName();
OneTimeWorkRequest worker = new OneTimeWorkRequest.Builder(CustomPeriodicallyWorker.class)
.setInitialDelay(timeValue, timeUnit)
.addTag(workerTag)
.setConstraints(Constraints.NONE)
.build();
WorkManager.getInstance(this).enqueueUniqueWork(workerTag, ExistingWorkPolicy.KEEP, worker);
}
// CustomPeriodicallyWorker.java:
public Result doWork(){
Log.v(TAG, "Work is in progress");
try {
CustomDateFormatter currentDateTime = new CustomDateFormatter();
CustomDateFormatter targetDateTime = new CustomDateFormatter();
targetDateTime.AddMinutes(20);
long timeDifference = targetDateTime.GetDateTime().getTime() - currentDateTime.GetDateTime().getTime();
OneTimeWorkRequest worker = new OneTimeWorkRequest.Builder(CustomPeriodicallyWorker.class)
.setInitialDelay(timeDifference, TimeUnit.MILLISECONDS)
.addTag(TAG)
.build();
WorkManager.getInstance(context).enqueueUniqueWork(TAG, ExistingWorkPolicy.REPLACE, worker);
} catch (Exception e) {
e.printStackTrace();
}
Log.v(TAG, "Work finished");;
return Result.success();
}
// The function in MainActivity.java that lists all scheduled worker:
private boolean ListScheduledWorker(String tag) {
WorkManager instance = WorkManager.getInstance(this);
ListenableFuture<List<WorkInfo>> statuses = instance.getWorkInfosByTag(tag);
try {
boolean running = false;
List<WorkInfo> workInfoList = statuses.get();
for (WorkInfo workInfo : workInfoList) {
Log.i(TAG, "Scheduled Worker running with ID: " + workInfo.getId());
WorkInfo.State state = workInfo.getState();
running = state == WorkInfo.State.RUNNING | state == WorkInfo.State.ENQUEUED;
}
return running;
} catch (ExecutionException e) {
e.printStackTrace();
return false;
} catch (InterruptedException e) {
e.printStackTrace();
return false;
}
}
// The ListScheduledWorker(String tag) prints me this out:
I/TAG: Scheduled Worker running with ID: 27bb31ed-5984-434f-a6ca-08b50462b3df
Scheduled Worker running with ID: 2d6abbb1-3a55-4652-83ca-60617631e0ab
Scheduled Worker running with ID: 3e89851d-7e0b-410d-86b8-e664a4d710f0
Scheduled Worker running with ID: 430e77b2-5fb8-4596-acd5-51e35a6a538b
Scheduled Worker running with ID: 73b57443-8195-4c55-a24d-bd643b88e13c
Scheduled Worker running with ID: 74c8a44b-2a9a-4448-b3d5-e2c085be3d06
Scheduled Worker running with ID: 75deabd3-08e8-403a-b9d7-6c23f114a908
Scheduled Worker running with ID: 89ec6239-e215-4ea1-a7bc-fcaa8b63065c
Scheduled Worker running with ID: 9363038e-be74-4a83-9d1f-eeeda35ebbfa
Scheduled Worker running with ID: 9a09806f-f0cf-43c1-a4f6-1f10448904f4
Scheduled Worker running with ID: c6686c56-fd8a-4866-8eb1-5124654b6cb7
Scheduled Worker running with ID: d3343328-db8f-4c8d-8055-a1acfc9d1c5c
Scheduled Worker running with ID: dea9272f-6770-45f0-ba66-2c845e156d7b
Scheduled Worker running with ID: eb4c111c-97c5-46c3-ba5c-ceefe652398c
Scheduled Worker running with ID: fc71f8dc-1785-43cd-9a44-1fe4e913ca6e
Scheduled Worker running with ID: fca1bcea-97d9-4066-8b5a-8b5496ffed1e
..and the list grows everytime when I rebuild/restart the App in Android Studio or on my physical device.

How to start an interactive java app with gradle

I want to write a gradle task that runs me this small application:
import java.lang.IllegalArgumentException
class TestApp{
companion object {
#JvmStatic
fun main(args:Array<String>){
val a = try{
args[0].toInt()
}catch (e:Exception) {throw argException}
val b = try{
args[1].toInt()
}catch (e:Exception) {throw argException}
print("$a + $b = ")
val answer = readLine()!!.toInt()
println(if(a+b == answer)"CORRECT" else "WRONG!")
}
private val argException:IllegalArgumentException by lazy { IllegalArgumentException("expecting two integers as args") }
}
}
If I run the application with, say, Intellij, the app will pause at the readline() and expect user input.
However, if I add a gradle task for it
task runTestApp(type:JavaExec){
main = "${javaMainTestApp}"
classpath = sourceSets.main.runtimeClasspath
}
and run, say,
gradle runTestApp --args="2 4"
Then I get
2 + 4 = Exception in thread "main" kotlin.KotlinNullPointerException
at [...].app.TestApp$Companion.main(TestApp.kt:19)
at [...].app.TestApp.main(TestApp.kt)
Why is that? And more importantly, how do I get the execution to wait for user input?
UPDATE
Thanks #tim_yates:
adding standardInput = System.in makes the app accept user input
but results in an output like:
3 + 5 =
<<==========---> 80% EXECUTING [20s]
> :runTestApp
8
where 8 is the user input.
consequently, when the app finishes, the output reads
3 + 5 =
<<======CORRECT> 80% EXECUTING [22s]
Maybe you could use the application plugin and do a gradle run. Or you could use the distribution plugin and run the script.

ChromeDriver's executeAsyncScript doesn't trigger ScriptTimeoutException properly

I wanted to implement script execution time handling, but stumbled upon this issue. If I design webdriver's script to execute in following manner, it successfully returns a variable, but it doesn't trigger ScriptTimeoutException as it should be. Any ideas why? I've adopted this script from webdriver's javadoc example
System.setProperty("webdriver.chrome.driver", "C:\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
//---setting script timeout to 1ns to force ScriptTimeoutException
driver.manage().timeouts().setScriptTimeout(1, TimeUnit.NANOSECONDS);
//this script works fine, ScriptTimeoutException is triggered
String script1 = "window.setTimeout(arguments[arguments.length - 1], 500);";
//this script is able to pass his return variable back to Java, but doesn't triggers ScriptTimeoutException
String script2 = "var callback = arguments[arguments.length - 1];" +
"var stringVar = 'abcd';" +
"callback(stringVar);";
while (true) {
Instant beforeScript = Instant.now();
//((JavascriptExecutor) driver).executeAsyncScript(script1);
String result = (String) ((JavascriptExecutor) driver).executeAsyncScript(script2);
System.out.println(result + " " + Duration.between(beforeScript, Instant.now()).toMillis());
}
Well, after searching for a while and discussing this with selenium\chromedriver developers, I've found that my script wasn't actually async script.
The proper async script that will throw ScriptTimeoutException would be something like this:
var callback = arguments[arguments.length - 1];
var stringVar = 'abcd';
setTimeout(()=>callback(stringVar), 100);

Akka actor pool for blocking requests

I am trying to use a thread pool to make blocking requests.
The problem is, each request is blocking the whole pool and items are process sequentially.
Not sure if this is even possible. Somebody please help
city-dispatcher {
type = Dispatcher
executor = "thread-pool-executor"
thread-pool-executor {
fixed-pool-size = 16
}
throughput = 100
}
And Java
Props props = Props.create(CityDataProcessorActor.class, psRespHolder).withDispatcher("akka.actor.city-dispatcher");
SmallestMailboxPool pool = new SmallestMailboxPool(10);
ActorRef cityRequestActorPool = actorSystem.actorOf(pool.props(props), "city-request-route");
for (String city : citiesArray) {
Future<Object> future = Patterns.ask(cityRequestActorPool, new CityCommand(city.trim()), timeout);
Object results = Await.result(future, duration);
log.info(results.toString());
}
As #Mon Calamari mentioned
Object results = Await.result(future, duration); is a blocking call. you can try future with callback
future onComplete{
case Success()=> println(result)
case Failure()=> println("some error")
}
Mon Calamari's comment is exactly correct. Here's an implementation. It will create a List of Futures as you create them. Then it blocks on the collected Futures sequentially to log each one. The awaits should become trivial as the iteration progresses, providing later Futures have completed in similar time.
....
Array<Future<Object>> futures = new ArrayList<>();
for (String city : citiesArray) {
Future<Object> future = Patterns.ask(cityRequestActorPool, new CityCommand(city.trim()), timeout);
futures.add(future);
}
for (<Future<Object>> f :futures){
Object results = Await.result(f, duration);
log.info(results.toString());
}

Categories

Resources