Java client uses one thread for prompting in command line, and another for socket messaging - client-server

Java server-client program where server runs a thread for each client and the client interfaces with the user via a guided menu at the command line.
I trying to have the client main thread handle receiving messages from the server and associated processing including sending responses and generate a new thread to prompt the user.
My reasoning for this was the client could receive messages from the server while the menu is prompted and waiting for input. Here's the basics:
class Client {
Client() {
} //constructor
public static void main(String[] args) {
Client c = new Client();
//other things
MenuThread mt = new MenuThread();
mt.start();
//other things
}
class MenuThread extends Thread {
public MenuThread() {
} //constructor
#Override
public void run() {
//menu & other things
}
Also in my Client class main thread, an event happens and my MenuThread needs to reset. So I interrupt it and start a new one:
menuThread.interrupt();
menuThread = new MenuThread();
menuThread.start();
Now, I'm having weird problems at the command line, as if multiple MenuThreads are left running. (1) Does this Thread approach seem logical (unfamiliar with Runnable nuances)? (2) Any idea what would be causing what seems like concurrency problems? The interrupt and start a new thread seems like a viable approach to me to be implement in the Client class main thread to reset the menu that is displayed by MenuThread at the command line.

Related

Order of execution between CommandLineRunner run() method and RabbitMQ listener() method

My Spring Boot application is subscribing to an event via RabbitMQ.
Another web application is responsible for publishing the event to the queue which my application is listening to.
The event basically contains institute information.
The main application class implements CommandLineRunner and overrides run() method.
This run() method invokes a method to create admin user.
When my application is started, and when an event is already present in queue, the listener in my application is supposed to update the Admin user's institute id.
However it looks like createAdmin() and the listener() are getting executed in parallel and institute id is never updated. Help me in understanding the control flow.
See below the code snippet and the order of print statements.
#SpringBootApplication
public class UserManagementApplication implements CommandLineRunner{
public static void main(String[] args) {
SpringApplication.run(UserManagementApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
createAdmin();
}
private void createAdmin() {
System.out.println("************** createAdmin invoked *********************");
Optional<AppUserEntity> user = appUserService.getUserByUserName("superuser");
if(!user.isPresent()) {
AppUserEntity superuser = new AppUserEntity();
superuser.setUsername("superuser");
superuser.setAppUserRole(AppUserRole.SUPERADMIN);
superuser.setInstId(null); // will be set when Queue receives Institute information
appUserService.saveUser(superuser);
System.out.println("************** superuser creation SUCCESSFUL *********************");
}
}
}
#Component
public class InstituteQueueListener {
#RabbitListener(queues = "institute-queue")
public void updateSuperAdminInstituteId(InstituteEntity institute) {
System.out.println("************** RabbitListener invoked *********************");
Long headInstituteId = institute.getInstId();
Optional<AppUserEntity> user = appUserService.getUserByUserName("superuser");
if(user.isPresent()) {
System.out.println("************* superuser is present *****************");
AppUserEntity superuser = user.get();
superuser.setInstId(headInstituteId);
System.out.println("************* Going to save inst Id = "+headInstituteId);
appUserService.saveUser(superuser);
}
System.out.println("************** superuser is NOT present (inside Q listener)*********************");
}
}
Order of print statements ....
(the queue already has event before running my application)
System.out.println("************** createAdmin invoked *********************");
System.out.println("************** RabbitListener invoked *********************");
System.out.println("************** superuser is NOT present (inside Q listener) *********************");
System.out.println("************** superuser creation SUCCESSFUL *********************");
When you start your application, any CommandLineRunners are called on the main thread (the thread on which you called SpringApplication.run). This happens once the application context has been refreshed and all of its beans have been initialized.
#RabbitListener-annotated methods are called by a message listener container once the container has been started and as messages become available. The container is started as part of the application context being refreshed and, therefore, before your command line runner is called. The container uses a separate pool of threads to call its listeners.
This means that your listener method may be called before, at the same time, or after your command line runner, depending on whether there is a message (event) on the queue.

JavaFX image not changing when function is called by Platform.runLater

I have a function to change an image and its opacity in a JavaFX GUI:
private static Image image = null;
private static ImageView imageView = new ImageView();
// some code to add image in GUI
public static void changeImage() {
imageView.setOpacity(0.5);
imageView.setImage(null);
}
When I call this function within the JavaFX instance, the image disappears or is changing if I use an image instead of null for setImage(). I tried calling the function by pressing a button.
In this case all works as I expected.
When I call this function from another class, the actual image will change its opacity, but the image itself is never changing. I call the function the following way:
public static void changeImg() {
Platform.runLater(() -> FX_Gui.changeImage());
}
Changing labels, progess bars... all works, but I did not manage to change an image.
There's a lot of aspects to this question that don't make sense.
Generally speaking, the GUI in JavaFX is intended to be self-contained and non-linear in it's execution. Programming an outside method to assume some state of the GUI, and then to directly manipulate the GUI based on that assumption is not the correct approach. So any attempt to know the state of the GUI by kludging in a Thread.sleep() call is inherently incorrect.
The new JFXPanel() call is not needed, as Application.launch() will initialize JavaFX. Presumably, this was added before the sleep(500) was put in, since calling changeImg() would fail if run immediately after the Thread.start() command, since the launch() wouldn't have time to even start yet.
As has been noted, having some kind of startup image that's replaced once the screen completes initialization should be done from within the FX_Min.start(Stage) method, although it's highly unlikely that you'd even see the first image.
The question seems to be aimed at designing a kind of application where the GUI is just some small part of it and the main application is going to go on to do lengthy processing and then trigger the GUI to something in response to the results of that processing. Or perhaps the main application is monitoring an external API and feeding updates to GUI periodically. In most cases, however, the GUI is usually initialized so that it can take control of the operation, launching background threads to do the lengthy processing and using JavaFX tools to handle the triggering of GUI updates and intake of results.
In the instance that the design really needs to have something other than the GUI be the central control, then use of Application does not seem appropriate. It is, after all, designed to control the Application, and monitors the status of the GUI once it's been launched to shut everything down when the GUI is closed. This is why the OP had to put the Application.launch() call in a separate thread - launch() doesn't return until the GUI shuts down.
If the application outside of the GUI is going to control everything then it's best to manually start JavaFX with Platform.startup(), and handle all the monitoring manually. The following code doesn't do any monitoring, but it does start up the GUI and change the image without any issues:
public class Control_Min {
public static void main(String[] args) {
Platform.startup(() -> new Fx_Min().start(new Stage()));
Platform.runLater(() -> Fx_Min.changeImage());
}
}
Note that no changes are required to the OP's code in Fx_Min. However, there's no reason for Fx_Min to extend Application any more, and the code from its start() method can be placed anywhere.
It should be further noted that, although this works, it's really way outside the norm for JavaFX applications. It's possible that the OP's situation really does require this kind of architecture, but that would place it into a very small minority of applications. Designing the application around Application.launch() and initiating lengthy processing in background threads through the JavaFX tools provided is almost always a better approach.
OK, so given new information from the OP it's clear that this should be based on Application and that the GUI should launch some kind of socket listener that would presumably block waiting for input.
Anything that blocks can't run on the FXAT, and there needs to be a way to allow the socket listener to communicate back to the GUI when it receives data. Ideally, the socket listener should be JavaFX unaware, and just plain Java.
IMO, the best way to do this is to provide a Consumer to accept information from the socket listener, and to pass it to the socket listener in it's constructor. That way, the GUI knows nothing about the nature of the socket listener except that it has a dependency on requiring a message consumer. Similarly, the socket listener has no knowledge about what invoked it, just that it has given it a message consumer.
This limits your coupling, and you are free to write your GUI without worrying about any of the inner workings of the socket listener, and visa versa.
So here's the GUI, cleaned up and simplified a bit so that the socket listener stuff is easier to follow. Basically, the GUI is just going to throw the message from the socket listener into a Text already on the screen. The message consumer handles the Platform.runLater() so that the socket listener isn't even aware of it:
public class Fx_Min extends Application {
#Override
public void start(Stage primaryStage) {
ImageView imageView = new ImageView(new Image("/images/ArrowUp.png"));
Text text = new Text("");
primaryStage.setScene(new Scene(new VBox(10, imageView, text), 800, 600));
primaryStage.setResizable(true);
primaryStage.show();
imageView.setImage(new Image("/images/Flag.png"));
new SocketListener(socketMessage -> Platform.runLater(() -> text.setText(socketMessage))).startListening();
}
public static void main(String[] args) {
launch(args);
}
}
Here's the socket listener. Clearly, this isn't going to listen on a socket, but it loops around a sleep() to simulate action happening on the Pi. The message format here is String, just to keep everything simple, but obviously this is the worse possible choice for an actual implementation of this. Build a special message class:
public class SocketListener {
private Consumer<String> messageConsumer;
public SocketListener(Consumer<String> messageConsumer) {
this.messageConsumer = messageConsumer;
}
public void startListening() {
Thread listenerThread = new Thread(() -> listenForIRCommand());
listenerThread.setDaemon(true);
listenerThread.start();
}
private void listenForIRCommand() {
for (int x = 0; x < 100; x++) {
try {
Thread.sleep(5000);
messageConsumer.accept("Station " + x);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
It should be really clear that since the call to listenForIRCommand() is executed from inside a background thread, that it's completely freed from any JavaFX contstraints. Anything that generally possible in Java can be done from there without worrying about it's impact on the GUI.
In the meantime I found out that the reason for not changing the image is that I run changeImage() before the initialization of the GUI is completed. If I wait about 500 mS before I sent the changeImage() command all works fine.
Below is the minimal code that demonstrates the issue I had:
import javafx.application.Application;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
public class Control_Min {
public static void changeImg() {
Platform.runLater(() -> Fx_Min.changeImage());
}
public static void main(String[] args) {
new Thread() {
public void run() {
Application.launch(Fx_Min.class);
}
}.start();
// JFXPanel will initialize the JavaFX toolkit.
new JFXPanel();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
changeImg();
}
}
And the Gui itself:
public class Fx_Min extends Application {
private static Stage stage;
private static GridPane rootPane;
private static Scene scene;
private static Image image = null;
private static ImageView imageView = new ImageView();
#Override
public void start(Stage primaryStage) {
stage = primaryStage;
rootPane = new GridPane();
scene = new Scene(rootPane,800,600);
try {
image = new Image(new FileInputStream("C:\\Users\\Peter\\eclipse-workspace\\FX_Test\\src\\application\\Image1.jpg"));
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
imageView.setImage(image);
rootPane.add(imageView, 1, 0);
stage.setScene(scene);
stage.setResizable(true);
stage.show();
System.out.println("Gui is ready");
}
public static void changeImage() {
try {
image = new Image(new FileInputStream("C:\\Users\\Peter\\eclipse-workspace\\FX_Test\\src\\application\\Image2.jpg"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
imageView.setImage(image);
System.out.println("Image Changed");
}
public static void main(String[] args) {
launch(args);
}
}
This code works fine.
In the console I get:
Gui is ready
Image Changed
When I remove the Thread.sleep(500) the image will not change.
In the console I get:
Image Change
Gui is ready
My conclusion is that I have send the runlater method before the FX runtime has been initialized.
(Have not fixed the static issue yet as this was not the issue. I will do in my original program later.)
My task is the following:
I program a GUI for my internet radio player on my PC.
The GUI controls the radio and polls what is playing.
I want to control the radio by an IR remote control too.
I have already a Raspberry Pi that communicates with the remote.
Therefore, my plan is to run a server socket on the PC, that receives the commands from the Raspberry Pi.
The server will run in its own thread. I want to use the runLater command to update the GUI.
Is there a better way to update the GUI from the server?
Goal is that the GUI will update immediately when I press a button on the remote.
With my latest learnings about JavaFX I will start the application now directly in the FX class and get the server thread started from the FX class

How to exit clean from WebAPI background service

The code below is a Web API that prints on behalf of a SPA. For brevity I've omitted using statements and the actual printing logic. That stuff all works fine. The point of interest is refactoring of the printing logic onto a background thread, with the web api method enqueuing a job. I did this because print jobs sent in quick succession were interfering with each other with only the last job printing.
It solves the problem of serialising print jobs but raises the question of how to detect shutdown and signal the loop to terminate.
namespace WebPrint.Controllers
{
public class LabelController : ApiController
{
static readonly ConcurrentQueue<PrintJob> queue = new ConcurrentQueue<PrintJob>();
static bool running = true;
static LabelController()
{
ThreadPool.QueueUserWorkItem((state) => {
while (running)
{
Thread.Sleep(30);
if (queue.TryDequeue(out PrintJob job))
{
this.Print(job);
}
}
});
}
public void Post([FromBody]PrintJob job)
{
queue.Enqueue(job);
}
}
public class PrintJob
{
public string url { get; set; }
public string html { get; set; }
public string printer { get; set; }
}
}
Given the way I acquire a thread to servicing the print queue, it is almost certainly marked as a background thread and should terminate when the app pool tries to exit, but I am not certain of this, and so I ask you, dear readers, for your collective notion of best practice in such a scenario.
Well, I did ask for best practice.
Nevertheless, I don't have long-running background tasks, I have short-running tasks. They arrive asynchronously on different threads, but must be executed serially and on a single thread because the WinForms printing methods are designed for STA threading.
Matt Lethargic's point about possible job loss is certainly a consideration, but for this case it doesn't matter. Jobs are never queued for more than a few seconds and loss would merely prompt operator retry.
For that matter, using a message queue doesn't solve the problem of "what if someone shuts it down while it's being used" it merely moves it to another piece of software. A lot of message queues aren't persistent, and you wouldn't believe the number of times I've seen someone use MSMQ to solve this problem and then fail to configure it for persistence.
This has been very interesting.
http://thecodelesscode.com/case/156
I would look at your architecture at a higher level, doing 'long running tasks' such as printing should probably live outside of you webapi process entirely.
If this we myself I would:
Create a windows service (or what have you) that has all the printing logic in it, the job of the controller is then to just talk to the service either by http or some kind of queue MSMQ, RabbitMQ, ServiceBus etc.
If via http then the service should internally queue up the print jobs and return 200/201 to the controller as soon as possible (before printing happens) so that the controller can return to the client efficiently and release it's resources.
If via a queuing technology then the controller should place a message on the queue and again return 200/201 as quick as possible, the service can then read the messages at it's own rate and print one at a time.
Doing it this way removes overhead from your api and also the possibility of losing print jobs in the case of a failure in the webapi (if the api crashes any background threads may/will be effected). Also what if you do a deployment at the point of someone printing, there's a high chance the print job will fail.
My 2 cents worth
I believe that the desired behavior is not something that should be done within a Controller.
public interface IPrintAgent {
void Enqueue(PrintJob job);
void Cancel();
}
The above abstraction can be implemented and injected into the controller using the frameworks IDependencyResolver
public class LabelController : ApiController {
private IPrintAgent agent;
public LabelController(IPrintAgent agent) {
this.agent = agent;
}
[HttpPost]
public IHttpActionResult Post([FromBody]PrintJob job) {
if (ModelState.IsValid) {
agent.Enqueue(job);
return Ok();
}
return BadRequest(ModelState);
}
}
The sole job of the controller in the above scenario is to queue the job.
Now with that aspect out of the way I will focus on the main part of the question.
As already mentioned by others, there are many ways to achieve the desired behavior
A simple in memory implementation can look like
public class DefaultPrintAgent : IPrintAgent {
static readonly ConcurrentQueue<PrintJob> queue = new ConcurrentQueue<PrintJob>();
static object syncLock = new Object();
static bool idle = true;
static CancellationTokenSource cts = new CancellationTokenSource();
static DefaultPrintAgent() {
checkQueue += OnCheckQueue;
}
private static event EventHandler checkQueue = delegate { };
private static async void OnCheckQueue(object sender, EventArgs args) {
cts = new CancellationTokenSource();
PrintJob job = null;
while (!queue.IsEmpty && queue.TryDequeue(out job)) {
await Print(job);
if (cts.IsCancellationRequested) {
break;
}
}
idle = true;
}
public void Enqueue(PrintJob job) {
queue.Enqueue(job);
if (idle) {
lock (syncLock) {
if (idle) {
idle = false;
checkQueue(this, EventArgs.Empty);
}
}
}
}
public void Cancel() {
if (!cts.IsCancellationRequested)
cts.Cancel();
}
static Task Print(PrintJob job) {
//...print job
}
}
which takes advantage of async event handlers to process the queue in sequence as jobs are added.
The Cancel is provided so that the process can be short circuited as needed.
Like in Application_End event as suggested by another user
var agent = new DefaultPrintAgent();
agent.Cancel();
or manually by exposing an endpoint if so desired.

JMS Persistent delivery mode

I am learning JMS and came across this statement: http://docs.oracle.com/javaee/1.3/jms/tutorial/1_3_1-fcs/doc/advanced.html#1023387
The PERSISTENT delivery mode, the default, instructs the JMS provider
to take extra care to ensure that a message is not lost in transit in
case of a JMS provider failure. A message sent with this delivery mode
is logged to stable storage when it is sent.
If JMS Provider failure occurs then how the JMS Provider can ensure that a message is not lost?
What does it mean that:
"A message sent with this delivery mode is logged to stable storage when it is sent."
Please help me in understanding the JMS concept here.
It means the message with PERSISTENT delivery mode is not lost when a messaging provider goes down for any reason and comes up again. The messaging provider saves messages with PERSISTENT delivery mode to disk and when the message provides restarts, the message is read from the disk and brought into memory.
Hope this is clear.
You can do a simple test to understand the concept. Refer the tutorial here on how to create producer and consumer.
You will see producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
Change it to producer.setDeliveryMode(DeliveryMode.PERSISTENT);
Now create two classes. One which calls only Producers and one only consumer.
public class AppOnlyProduce {
public static void thread(Runnable runnable, boolean daemon) {
Thread brokerThread = new Thread(runnable);
brokerThread.setDaemon(daemon);
brokerThread.start();
}
public static void main(String[] args) throws InterruptedException {
thread(new HelloWorldProducer(), false);
thread(new HelloWorldProducer(), false);
}
}
public class AppOnlyConsumer {
public static void thread(Runnable runnable, boolean daemon) {
Thread brokerThread = new Thread(runnable);
brokerThread.setDaemon(daemon);
brokerThread.start();
}
public static void main(String[] args) throws InterruptedException {
thread(new HelloWorldConsumer(), false);
thread(new HelloWorldConsumer(), false);
}
}
First run AppOnlyProduce. It will create two messages. Now run AppOnlyConsumer it will read two messages.
Now change back the line to producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
Again run AppOnlyProduce. It will create two messages. Now run AppOnlyConsumer You will see that it waits for sometime for message and they say Received: null
In first case mode was persistent. So though Java program ended messages were persisted and made available when JMS started (this time by consumer)
In second case mode was not persistent. So messages vanished as soon as program ended.

Windows Service doesn't stop 'Starting'

I've created a service and an installer. I've installed my service on the computer. In the services screen, I can see that the service is Starting. It won't stop Starting, I can't pause it, nothing. The only thing I can do is to deinstall.
I've tried attaching Visual Studio to the proces, but nothing really happens. How can I debug this service? I'd like to know what is going on.
This usually happens if you have too much/all of your code running inside your OnStart handler - you're meant to kick things off in there and then return. It's only once you return that your service is considered started.
You'd typically create one or more new Threads that run the code you want running all of the time, Start() them and then return. Or create objects that implicitly run their own threading (e.g. WCF's ServiceHost).
Then, it's your job in OnStop to shut them down gracefully - e.g. Set a ManualResetEvent and then Join on those threads.
e.g your class might look like this (not tested)
public class MyService : ServiceBase {
private ManualResetEvent _stop = new ManualResetEvent(false);
private Thread _worker;
public override void OnStart(string[] args) {
_worker = new Thread(DoStuff);
_worker.Start();
}
public override void OnStop() {
_stop.Set();
_worker.Join();
}
private void DoStuff() {
while(!_stop.WaitOne(0)) {
//Do something useful here.
}
}
}

Resources