Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug Report: Payara 6.2024.6, @Clustered @Singleton not work as expected. #6964

Closed
cidylong opened this issue Sep 22, 2024 · 4 comments
Closed
Assignees
Labels
Type: Bug Label issue as a bug defect

Comments

@cidylong
Copy link

Brief Summary

Payara 6.2024.6 community version, @clustered & @singleton annotations Timer EJB not work as expected.

Expected Outcome

@clustered and @singleton Time EJB should instanced on only one node in cluster.

Current Outcome

Actually, there are two Timer EJB instances created in a four members cluster.

Reproducer

Create a four members cluster, server instances as: DAS, AppServerLocal, AppServerRemote, MigAppServer on separated machines.

DAS and AppServerLocal were deployed on 10.0.1.103 (physical Linux Rocky 9);
AppServerRemote and MigAppServer were deployed on 10.0.1.104 (physical Linux Rocky 9);

Developed a set of applications (include service EJB and Web applications) deployed on different server instance.

Developed a clustered & singleton timer EJB to manage business process (have to be Cluster wise singleton to make suer only one EJB instance work at the moment.)

Code as:

@Clustered(callPostConstructOnAttach = true, callPreDestroyOnDetach = true, keyName = "clusteredSingletonTimer", lock  = DistributedLockType.LOCK)
@Singleton
@Startup
public class ClusteredSingletonTimer implements Serializable {
  private static final transient Logger logger = Logger.getLogger(ClusteredSingletonTimer.class.getName());

@Resource
transient TimerService ts;
@Resource
private transient SessionContext context;
@Lock
@Timeout
public void executor() {
    StatementPaymentScanner scanner = new StatementPaymentScanner();
    scanner.writeEvent();
    logger.info("EJB businessMethod()");
}
@PostConstruct
void init() {
    /*TimerConfig sTimerConfig = new TimerConfig();
    sTimerConfig.setInfo("DailyTimer_Clustered_singleton");
    ScheduleExpression schedule = new ScheduleExpression();
    schedule.hour("22").minute("47").second("13");*/
    /*context.getTimerService().createCalendarTimer(schedule, sTimerConfig);*/
    Timer timer = ts.createTimer(18000, 600000, "Statement-roller-Timer");/*15 minutes rolling*/
    logger.info("Cluster-wide Construction");
}
@PreDestroy
void destroy() {
    logger.info("Instance-only destruction");
}
}

Java class StatementPaymentScanner will create verify information and write to event log. The log information will include time out fired: server instance IP, Server name and Hazelcast Instance name to help us to find out where server instance is hosting that EJB timer instance.

Deploy it to MigAppServer

Restart domain and all server instances;

When time out, we will get result from event logger.

There are the result as:

Screenshot 2024-09-22 at 10 38 07 AM
Screenshot 2024-09-22 at 10 38 29 AM

From above screen shots you can see, there are two EJB timer instances existed in the cluster by different hosts and Hazelcast instances (one named: loving_pike and other one name: affectionate_yonath) and the two EJB timer fired at about the same time as well. (one: 2024-09-22 10:36:13 other one: 2024-09-22 10:36:13)

This will cause serious issue when the processes trying to access Database and Hazelcast DataGrid, Concurrency and data corruption will cause business application mess.

This issue is very easy to reproduce, please report it as high priority bug to be fixed or advise urgent work around.

Operating System

Rocky Linux 9

JDK Version

JDK 17.0.3

Payara Distribution

Payara Server Full Profile

@cidylong cidylong added Status: Open Issue has been triaged by the front-line engineers and is being worked on verification Type: Bug Label issue as a bug defect labels Sep 22, 2024
@lprimak
Copy link
Contributor

lprimak commented Sep 22, 2024

You have callPostConstructOnAttach = true which means @PostConstruct gets called on every Payara instance.
Then, you schedule the timer on every instance. This forces your timeouts to get called on every instance.

Also, you have transient on SessionContext and TimerService which isn't going to work
I would suggest you use @Schedule annotation instead,
and verify that your timers work properly without @Clustered singleton first, since they may require some configuration.
@Clustered doesn't affect how timer work at all, they are separate systems.

@cidylong
Copy link
Author

@lprimak , Thank you for your advice. I will disable callPostConstructOnAttach and callPreDestroyOnDetach, try it again.

@fturizo fturizo removed the Status: Open Issue has been triaged by the front-line engineers and is being worked on verification label Sep 24, 2024
@fturizo
Copy link
Contributor

fturizo commented Sep 24, 2024

@cidylong, based on your report, you intend to use a clustered singleton to configure an EJB timer to run only ONCE per cluster instead of on each node.

As per the official documentation of the clustered singleton feature on timer usage you don't need to use a clustered singleton and switch to stateless bean and configure your timer to be persistent using the @Schedule annotation as @lprimak suggested.

Since there are no bugs detected on this issue, we'll proceed to close it.

@fturizo fturizo closed this as completed Sep 24, 2024
@cidylong
Copy link
Author

@lprimak, @fturizo, Thank you for your advice. I tested @lprimak's advice, it is works as expected. Thank you again.

You are welcome to close this report.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Bug Label issue as a bug defect
Projects
None yet
Development

No branches or pull requests

4 participants