Seems I met the same problem though I don't have any customized services implemeting/extending Runnable.

@Startup
public static void scheduleJobs(PeriodicExecutor executor, final MailService mailService,final IOSPushService pushService,
final Logger logger)
{
executor.addJob(new IntervalSchedule(300000), "Mail Service", new Runnable()
{
@Override
public void run()
{
try
{
mailService.sendPendingMails();
}
catch (Exception ex)
{
logger.error("Failed to send mails.", ex);
}
}
});

executor.addJob(new IntervalSchedule(300000), "IOS Push Service", new Runnable()
{
@Override
public void run()
{
try
{
pushService.checkAndPushNewAlerts();
}
catch (Exception ex)
{
logger.error("Failed to push IOS notifications.", ex);
}
}
});
logger.info("Jobs scheduled.");
}

In the log, I saw this:
2013-04-14 14:37:11 [INFO] TapestryIOCModule.RegistryStartup Jobs scheduled.
2013-04-14 14:37:17 [INFO] TapestryIOCModule.RegistryStartup Jobs scheduled.
2013-04-14 14:37:23 [INFO] TapestryIOCModule.RegistryStartup Jobs scheduled.

于 2012/11/28 0:30, Christian Riedel 写道:
Hi everyone,

I wrote about this bug a while ago already, but can't find the original post.
After lots of debugging I found the reason for a bug in our app. The symptoms 
were that all contributions annotated with @Startup (also the ones from 
Tapestry internal modules) were executed a second time as soon as the app has 
been hit by its first request, i.e. some services got realized.

Now I found the reason and I'm not sure whether it's a real bug in Tapestry or 
if it's a less known side effect of Tapestry's design…

Custom services that implement "Runnable" and have any contributions will cause 
Tapestry to assume all of RegistryStartup's contributions to be matching as well, so 
they'll be executed as soon as that custom service's contributions are executed. If you 
have some execute-one-time-only startup-contributions you might get into troubles!

Debug here: 
org.apache.tapestry5.ioc.internal.ModuleImpl#markerMatched(ServiceDef 
serviceDef, Markable markable)

"markable" may be any contribution for RegistryStartup.
Then "markable.getServiceInterface()" will return the "Runnable" interface, which is 
assignable to your custom service and further down that method the contribution that was supposed to be for 
RegistryStartup will be considered as "ContributionDef".

Sure the fixing the bug is easy:
Just NEVER let any of your services implement Runnable. Why did we do that in 
the first place? Because we wanted to add a job to Tapestry's PeriodicExecutor 
after our custom service got realized, to prevent some timing issues. So our 
services wanted to be a PeriodicExecutor-job.

Another fix for the bug could be to give RegistryStartup its own interface and 
prevent collisions with internal services altogether!

Hope to read some thoughts of committers on that issue.


Cheers
Christian
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org




---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org

Reply via email to