Restarting TagProvider after module upgrade

So we have our custom TagProvider, so we naturally implement startup(TagSubscriptionModel subModel) and shutdown();

We also have our ModuleGatewayHook which extends AbstractGatewayModuleHook

When we upgrade our module, the ModuleGatewayHook will shutdown(), and then setup/startup with the new version.

However, the TagProvider keeps running using the old bytecode. Our workaround is to save the provider record without changes and that triggers it to re-load.

So what are we missing, or what would be the recommended way to trigger an automatic reload of our TagProvider when a new version of the module is loaded?

Thanks!
Ivan

Are you removing your custom provider type on shutdown?

we are:

[code]@Override
public void shutdown() {

try {
	context.getTagManager().removeSQLTagProviderType(ourTagProviderType);
} catch (Exception e) {
	logger.error("Error removing cTalk Tag Provider Type", e);
}

}[/code]

When we load a new version of the module, the log looks like this:

code 2015-08-11 2:23:21 PM ModuleManager Starting up module ‘ctalk’ v1.0.0 (b29)…
(I) 2015-08-11 2:23:21 PM ModuleManager Starting up module ‘ctalk’ (v1.0.0 (b29))…
(I) 2015-08-11 2:23:21 PM ModuleManager Shutdown of module “ctalk” completed in 0 ms
(I) 2015-08-11 2:23:21 PM ModuleManager Shutting down module ‘ctalk’ v1.0.0 (b28)…
(I) 2015-08-11 2:23:21 PM ModuleManager Installing module: “ctalk”[/code]

But any tag provider that is configured is not updated until we save the realtime provider record. Then it looks like this:

code 2015-08-11 2:23:59 PM BasicExecutionEngine Modifying an existing execution unit. [Owner=tag scanclasses [ctalktest], Name=defaulthistorical]
(I) 2015-08-11 2:23:59 PM BasicExecutionEngine Modifying an existing execution unit. [Owner=tag scanclasses [ctalktest], Name=default]
(I) 2015-08-11 2:23:59 PM Provider[CTalkTest] CTalk TagProvider [CTalkTest] started
(I) 2015-08-11 2:23:59 PM TagStore Starting tag store for connection ‘MySQLConnection’
(I) 2015-08-11 2:23:59 PM Provider[CTalkTest] CTalk TagProvider shut down CTalkTest
(I) 2015-08-11 2:23:59 PM SQLTagsManagerImpl Tag provider record updated
[/code]

On the logging/levels page of the gateway, find “SQLTags.Manager” and turn it to DEBUG level. Then restart your module and look for messages about unregistering tag providers. You might also put an INFO level logger in your tag provider’s shutdown() method to see if it’s being called.

Sorry about the delay here, continuing now.

SQLTags.Manager shows nothing new in Debug level.

I also put ModuleManager to Debug level without additional information.

Tracing log calls show that both Setup and Shutdown are called as expected in the Hook class.

Shutdown is not called in the TagProvider class, until I save/modify the settings record.

I’m running out of ideas, but, is there any special format required for naming a tag provider? for example, this provider called “ebh”, I use the following code:

EbhTagProviderType ourTagProviderType = new EbhTagProviderType("ebh", "EBH Provider", "SQL Tags generated and executed by the EBH module.");

That is the type that I use with

context.getTagManager().addSQLTagProviderType(ourTagProviderType);

and with

context.getTagManager().removeSQLTagProviderType(ourTagProviderType);

Or could there be anything else happening, when I remove the SQLTagProviderType, that would stop the system from shutting down all providers of that type?

Thanks!

bump

Hi,

Sorry for the delay on this. Yes, you’re correct, we weren’t properly tracking the individual providers for each type, so the providers weren’t being shut down when the type was unregistered. This has been fixed for 7.7.6.

Regards,

Awesome. Thanks.

Can you see any trick that I could use to get it working with earlier versions? There’s just some systems that are operational where it is unfeasible to upgrade Ignition, but we could upgrade our module.

Cheers
Ivan

Hi,

I think one way or another you could probably work something up. The SQLTagsManager interface has another registerProvider function that takes a built provider. So, the following code would re-register all of the providers of your type:

List<SQLTagProviderRecord> existing = context.getPersistenceInterface().query(new SQuery<SQLTagProviderRecord>(SQLTagProviderRecord.META).eq(SQLTagProviderRecord.Type, myProvType.getTypeId())); for(SQLTagProviderRecord r : existing){ context.getTagManager().unregisterTagProvider(r.getName()); context.getTagManager().registerTagProvider(myProvType.createNewProvider(r, context)); }

The only trick of this is that when the system starts up, it’s also going to start all of the providers of your type. You would probably want to figure out a way to only do this on a reload. You might be able to do this by comparing the class loader of an existing tag provider vs. that of your tag provider type. Since your tag provider type is the one that instantiates the provider, and since the type is registered by your module, the class loader should be the same. I didn’t have a chance to try this out yet, but it might make the above look something like:

for (SQLTagProviderRecord r : existing) { if (context.getTagManager().getTagProvider(r.getName()) != null && context.getTagManager().getTagProvider(r.getName()).getClass().getClassLoader() != getClass() .getClassLoader()) { ...

There might be an easier way that’s not currently coming to mind.

This would be placed in the startup() function, where you probably are, and should continue, registering your tag provider type in the setup() function.

Regards,

Cheers, thanks Colby.