Hello,
I'm new to JIRA development and I'm following this article on implementing plugin caching: https://developer.atlassian.com/confdev/development-resources/confluence-developer-faq/how-do-i-cache-data-in-a-plugin
However, after installing my plugin and trying to test it, it does not behave as expected.
Each time I make a request to my plugin, it basically instantiates a new instance of my plugin. The constructor is called for every request I make, so a new CacheManager is created and each request does the expensive retrieval of data from the database. In other words, each request is like visiting my plugin for the very first time and effectively there is no caching because of this.
Why does my plugin not live beyond the scope of a single request? Is this perhaps a plugin scope configuration that I need to configure? I read the article about JIRA plugin lifecycle: https://developer.atlassian.com/jiradev/jira-platform/building-jira-add-ons/jira-plugins2-overview/jira-plugin-lifecycle#JIRAPluginLifecycle-Componentinitialisation and also read articles about "JIRA plugin scope" but they're not talking about plugin scope as it relates to development.
Thanks in advance!
You need to inject CacheManager. In this case CacheManager always stays the same. Also you can make your class as a bean adding Named annotation to the class. It is difficult to say for sure what is wrong with your code because you did not provide it.
Hi Alexey,
Thanks for your help! I am injecting the CacheManager into my constructor and also I have just tried adding the "Named" annotation, however it still does not work. Here is a simplified version of my plugin code:
@Named("MyPlugin")@Scannedpublic class MyPlugin extends JiraWebActionSupport{ private static final Logger log = LoggerFactory.getLogger(MyPlugin.class);private MyDBService db;@ComponentImport private final PermissionManager permissionMgr;@ComponentImport private final CacheManager cachMgr;private final Cache myCache; private List<MyField> myFields;@Inject public MyPlugin(MyDBService mydb, PermissionManager permissionMgr, CacheManager cachMgr) { this.db = mydb; this.permissionMgr = permissionMgr; this.cachMgr = cachMgr; myCache = cachMgr.getCache(MyPlugin.class.getName() + "-MyCache.cache", new MyDataLoader(), new CacheSettingsBuilder().expireAfterAccess(50, TimeUnit.MINUTES).build()); log.debug("MyPlugin Constructor called!"); }@Override public String execute() throws Exception {myFields = (List<MyField>) myCache.get("myData") return super.execute(); }private class MyDataLoader implements CacheLoader<String,List<MyField>> {public List<MyField> load(@Nonnull String s) {if(s.equals("myData")) { log.debug("retrieved data from db!"); return db.getAllData(); }return null; } }}
You put @Named annotation and made atlas-clean and then atlas-run? And then every time you enter your webwork item you fall into the constructor? If so, make you private MyDataLoader class as a bean and pass it to the constructor.
Also I found this article
https://community.atlassian.com/t5/Answers-Developer-Questions/Cache-2-CacheLoader-is-called-on-every-cache-read/qaq-p/555222
The point is that
myCache = cachMgr.getCache(MyPlugin.class.getName() + "-MyCache.cache",new MyDataLoader(), new CacheSettingsBuilder().expireAfterAccess(50, TimeUnit.MINUTES).build());
must be called once. So I would make a bean and make the myCache as a property of the bean. Then I would inject it into the constructor of your Webwork.
But That would be true only if the constructor of your Webwork is called everytime you call the webwork. I need to check it. But I can not check it right now. But I ll try to check it tomorrow.
It looks like you're new here. Sign in or register to get started.