My application has stopped consuming from kafka's queue - java

I am developing an application based on Spring Boot and kafka queues, but when developing the main of the application, it has stopped consuming from the queue and I do not know why.
--Main Application---
#Service
public class ApplicationMainClass implements ApplicationListener<ApplicationReadyEvent> {
#Autowired
PlayerDaoRepository playerDaoRepository;
#Autowired
DataColectorServiceImp dataColectorServiceImp;
#Autowired
BattleDaoRepository battleDaoRepository;
#Autowired
BattleService battleService;
private static final Logger log = LogManager.getLogger(ApplicationMainClass.class);
#Override
public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
List<Playerdao> listPlayersActive;
List<BattleDao> battle;
List<BattleDao> battleDaoAux;
while (true) {
log.info("Comienza la ejecuciĆ³n");
listPlayersActive = playerDaoRepository.findByActive(true);
for (Playerdao player : listPlayersActive) {
try {
String battleString = dataColectorServiceImp.apiConexion(player.getUri());
if (battleString.equals("")) {
continue;
}
battle = player.getBatallasPlayed();
battleDaoAux = battleService.getBattle(battleString);
player.setLastGamePlayed(!battle.isEmpty() ? battle.get(battle.size()-1).getBattletlime() : LocalDateTime.MIN.toString());
battleDaoAux = player.kafkaHandler(battleDaoAux);
battleService.postBattle(battleDaoAux, player.getTag());
player.setBatallasPlayed(player.listBuilder(player.getBatallasPlayed(), battleDaoAux));
battleDaoRepository.saveAll(battle);
playerDaoRepository.save(player);
} catch (Exception e) {
log.error("", e);
}
}
try {
log.info("Termina la ejecucion");
Thread.sleep(60000);
} catch (InterruptedException e) {
}
}
}
}
StreamListener
#StreamListener
public KStream<IdBattle, textBattle>newBattle(#Input(BinderProcessor.battles)KStream<IdBattle,textBattle>battleKStream){
updateDatabase(battleKStream);
return null;
}
private void updateDatabase(KStream<IdBattle, textBattle> battleKStream) {
battleKStream.foreach((IdBattle,textBattle)->{
if(textBattle==null){
playerDaoRepository.deleteById(IdBattle.getIdBattle());
}else{
Battle battle= playerDaoService.textTreatment(textBattle.getText(),Battle);
battle=battleDaoService.setBattleTime(textBattle.getText(),battle);
Event event = playerDaoService.textTreatmentEvent(textBattle.getText(),Event);
battle.setMap(event.getMap());
battleDaoService.updateDatabase(battle,IdBattle.getIdBattle());
}
});
}
}
I don't know how to fix it so that both threads of the application run at the same time, and in fact I don't even know why it has stopped consuming from the queue.
Thank you very much

Good, as we discussed in the comments the bug was based on that we can not make a thread that calls a sleep and a while true, because all the time will be using that thread and will not pass to the next, I have solved it by simply adding the tag "#Scheduled" to the main of the application.
This way we make sure that after the execution of the main we wait "x" seconds for the next execution, leaving resources for the streamListener.
Thank you very much and feel free to correct me if I have made a mistake in the explanation.

Related

Shutting Down Executor Service

I am working on an application, where I continuously read data from a Kafka topic. This data comes in String format which I then write to an xml file & store it on hard disk. Now, this data comes randomly and mostly it's supposed to come in bulk, in quick succession.
To write these files, I am using an Executor Service.
ExecutorService executor = Executors.newFixedThreadPool(4);
/*
called multiple times in quick succession
*/
public void writeContent(String message) {
try {
executor.execute(new FileWriterTask(message));
} catch(Exception e) {
executor.shutdownNow();
e.printStackTrace();
}
}
private class FileWriterTask implements Runnable{
String data;
FileWriterTask(String content){
this.data = content;
}
#Override
public void run() {
try {
String fileName = UUID.randomUUID().toString();
File file = new File("custom path" + fileName + ".xml");
FileUtils.writeStringToFile(file, data, Charset.forName("UTF-8"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
I want to know when should I shutdown my executor service. If my application was time bound, I would used awaitTermination on my executor instance, but my app is supposed to run continuously.
If in case of any exception, my whole app is killed, would it automatically shutdown my executor?
Or should I catch an unchecked exception and shutdown my executor, as I have done above in my code?
Can I choose not to explicitly shutdown my executor in my code? What are my options?
EDIT: Since my class was a #RestController class I used the following
way to shutdown my executor service
#PreDestroy
private void destroy() {
executor.shutdownNow();
if(executor != null) {
System.out.println("executor.isShutdown() = " + executor.isShutdown());
System.out.println("executor.isTerminated() = " + executor.isTerminated());
}
}
It is a good practice to shut down your ExecutorService. There are two types of shutdown that you should be aware of, shutdown() and shutdownNow().
If you're running you application on an application server with Java EE, you can also use a ManagedExecutorService, which is managed by the framework and will be shut down automatically.

Problems in achieving inter thread communication.

I am trying to learn threads in java, and got this idea of implementing a coin phone functionality using threads.
I am able to write down the basic tasks. My Flow chart is as below.
I have tried writing a class for checking hook status.
public class Hook {
static Logger log = Logger.getLogger(Hook.class.getName());
OffTheHook offTheHook= new OffTheHook();
void checkHook(Boolean hookStatus, String keyPressed){
log.debug("Hook Status "+hookStatus);
if(hookStatus==true){
offTheHook.beforeDroppingCoin(hookStatus);
}else{
if(keyPressed!=null){
DisplayMessages.displayMessage("FollowInstruction");
}else{
displayReadyMessage();
}
}
}
public static void displayReadyMessage(){
DisplayMessages.displayMessage("ready");
}
}
Another timer class..
public class TimerClass extends Thread{
int timeInMilli;
boolean status=false;
public TimerClass(int timeInMilli){
this.timeInMilli=timeInMilli;
}
#Override
public void run() {
timer();
}
private void timer(){
try {
Thread.currentThread().sleep(timeInMilli);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
How do I make these classes communicate with each other(small example will be enough). Moreover my requirement is if the headset is back on the hook the call must get cut.. How should I write the code to monitor that status? based on that status I need to make decision. At the same time I need to have another Thread that shall input status of hooks.
A small snippet of code will be that does the similar functionality, will be of great help.

When to shutdown ScheduledExecutorService?

I have a singleton that needs to start a scheduled execution. This is the code:
public enum Service{
INSTANCE;
private Service() {
startAutomaticUpdate();
}
private void startAutomaticUpdate() {
try {
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
executor.scheduleAtFixedRate(new AutomaticUpdate(), 0, 15, TimeUnit.MINUTES);
} catch (Exception e) {
LOG.error(e.getMessage() + "Automatic update not working: ");
}
}
//Makes a call to a webservice that updates a static variable.
private void getTemplateNames(){...}
private class AutomaticUpdate implements Runnable {
public AutomaticUpdate() {
}
#Override
public void run(){
try{
getTemplateNames();
}catch(Exception e){
LOG.error("Error in automatic update: "+e.getMessage());
}
}
}
I am not sure when or if I should call the shutdown method of the executor. I'm using JEE5, so I'm not sure if simply undeploying the app will automatically execute the shutdown, or if I am messing up big time and creating a ridiculous amount of threads and not killing them.
-EDIT-
I'll add a bit more info, just in case.
The whole app is a RESTful web app using Jersey as a ServletContainer.
You said JEE5? Why you're reeinventing the wheel?
Just create a EJB with #Schedule and #Startup
#Singleton
#Startup
public class TaskSingleton {
#Schedule(second = "0", minute = "*/15", hour = "*")//This mean each 15:00 minutes
public void getTemplateNames() {
// YOUR TASK IMPLEMENTATION HERE
}
}
No you don't mean JEE5 complaint server. :(
Go for the implementation with a ServletContextListener. I wrote some answer like that here, It's the same idea, it does applies here.

How Polling mechanism can be realized with RMI?

Following the design/architecture i created for multiuser/network turn-based game with RMI server callbacks, I have tried to create a distributed animation in which my model(Ball) is remote object and it updates the clients via callback mechanism from server.
The current situation of code is :
The model remote object, which is iterating client list and calling update method of them,
public class BallImpl extends UnicastRemoteObject implements Ball,Runnable {
private List<ICallback> clients = new ArrayList<ICallback>();
protected static ServerServices chatServer;
static ServerServices si;
BallImpl() throws RemoteException {
super();
}
....
public synchronized void move() throws RemoteException {
loc.translate((int) changeInX, (int) changeInY);
}
public void start() throws RemoteException {
if (gameThread.isAlive()==false )
if (run==false){
gameThread.start();
}
}
/** Start the ball bouncing. */
// Run the game logic in its own thread.
public void run() {
while (true) {
run=true;
// Execute one game step
try {
updateClients();
} catch (RemoteException e) {
e.printStackTrace();
}
try {
Thread.sleep(50);
} catch (InterruptedException ex) {
}
}
}
public void updateClients() throws RemoteException {
si = new ServerServicesImpl();
List<ICallback> j = si.getClientNames();
System.out.println("in messimpl " + j.size());
if (j != null) {
System.out.println("in ballimpl" + j.size());
for (ICallback aClient : j) {
aClient.updateClients(this);
}
} else
System.err.println("Clientlist is empty");
}
}
The client which is implementing callback interface and has update method implementation :
public final class thenewBallWhatIwant implements Runnable, ICallback {
.....
#Override
public void updateClients(final Ball ball) throws RemoteException {
try {
ball.move();
try {
Thread.sleep(50);
} catch (Exception e) {
System.exit(0);
}
} catch (Exception e) {
System.out.println("Exception: " + e);
}
}
.....
}
My general perception is that i m implementing pushing mechanism with RMI and in that scenario i need to implement polling)
if that is the case how can i implement the polling mechanism with RMI?
thanks for any feedback.
jibbylala
Polling is independent of the protocol you use to implement the client and server.
A client polls by looping endlessly. Inside the loop there's a request to the server for information. The server sends either the desired information or a "not ready" message back. The client does its thing and waits until the next request needs to be sent.
If you happen to choose RMI, it means an RMI client and server. But the polling mechanism is the same regardless.
Break the problem into pieces - it'll be easier to think about and solve that way.
Forget about polling to start. Can you write an RMI server, start it up, and create a separate client to make a single request? If you can do that, then you put it inside a loop with a sleep to implement the delay and you're done.
I don't belive you can implement a callback via Java RMI. You need to either setup polling as you have suggested, or make your "client" RMI servers can you can send message to them directly.
How could you do this differently? I would suggest using JMS messaging to send command objects to the clients, this would handle all the distribution for you.

How to lock a java method to protect multiple invocations

I have an application that every 15 minutes or so does a replication from a remote database. It just keeps the two repositories in sync. Once this replication is going it is not possible to do it again. I have setup the following structure but I'm not sure if it is the correct approach.
public class ReplicatorRunner {
private static Lock lock = new ReentrantLock();
public replicate() {
if (lock.tryLock()) {
try {
// long running process
} catch (Exception e) {
} finally {
lock.unlock();
}
} else {
throw new IllegalStateException("already replicating");
}
}
}
public class ReplicatorRunnerInvocator {
public void someMethod() {
try {
ReplicatorRunner replicator = new ReplicatorRunner();
replicator.replicate();
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
}
The ReplicatorRunner is the class owning the method replicate which can only be run one at a time.
Edit.
I need the next call to fail (not block) if the method is already running on any instance.
This looks good. ReentrantLock.tryLock() will only give the lock to one thread, so synchronized is not necessary. It also prevents the blocking inherent in synchronization that you say is a requirement. ReentrantLock is Serializable, so should work across your cluster.
Go for it.
Change public replicate() to public synchronized replicate()
That way replicate will only ever allow access to one thread at a time. You'll also be able to delete the ReentrantLock and all associated code.
I ended up using the following:
public class ReplicatorRunner {
private static Semaphore lock = new Semaphore(1);
public replicate() {
if (lock.tryAcquire()) {
try {
// basic setup
Thread t = new Thread(new Runnable() {
public void run() {
try {
// long running process
} catch Exception (e) {
// handle the exceptions
} finally {
lock.release();
}
}
})
t.start();
} catch (Exception e) {
// in case something goes wrong
// before the thread starts
lock.release();
}
} else {
throw new IllegalStateException("already replicating");
}
}
}
public class ReplicatorRunnerInvocator {
public void someMethod() {
try {
ReplicatorRunner replicator = new ReplicatorRunner();
replicator.replicate();
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
}
Without looking at the specifics of the ReentrantLock, it occurs to me that this prevention of multiple simultaneous replication routines will be limited to a single JVM instance.
If another instance of the class is kicked off in a separate JVM, then you might be in trouble.
Why not put a lock mechanism on the database? i.e. A row in a control table that is set to a value depicting whether or not the replication is busy running, and reset the value when the replication is finished.
take a look at the Semaphore class here or mark the method as synchronized
the thread executing the method at any given time owns a lock on it avoiding other threads to call the method until its execution ends.
Edit: if you want the other threads to fail, you could use a Lock, and test if the lock is avaible by the tryLock method.

Categories