Can I persist state between Jenkins shared library calls? - jenkins

I would like to persist the state of some logic between calls in my Jenkins shared library. I don't want to pass in an object/map/... with the state in the arguments but use some kind of global variable/map for this. I failed with global varibales in the foobar.groovy below or use of environment variables. I found a work-around by creating a small helper class with a static map to store my data but this does not seem to be the right solution. Is there a cleaner way?
src/pkg/GlobalConfig.groovy
package pkg;
class GlobalConfig {
// define a static map
static Map data = new HashMap()
}
use map in shared library e.g. vars/foobar.groovy
import pkg.GlobalConfig
def do_something() {
def data = pkg.GlobalConfig.data
// do something with data
}

Related

library Jenkins Step is not working to dynamically load methods

I want to create a new instance of a class which is in src folder in my shared library. Of cource I can do a simple def object = new myClass() with an import on the top but I want to do it dynamically initiate classes (trying to use Class.forName failed for me and I'm not going to use that solution).
I'm trying to do this from a groovy file which is under vars folder and not src.
So what I do is : def customized = library("mySharedLib").com.x.x.MyClass.new(this)
As it is specified in the documentation for Shared libraries : Step library
But I'm getting the error :
java.lang.IllegalAccessException: com.x.x.MyClass was defined in file:///Path/to/master/workspace/jobs/project/builds/297/libs/mySharedLib/vars/generic.groovy which was not inside file:///Path/to/master/workspace/jobs/project/branches/PR-50/builds/297/libs/mySharedLib/src/
In the Jenkins Jira Here, there is the same issue... any ideas ?? I can't understand wht is going on! I tried making a method in a class under src folder that does the step library call but it returns same error.
No need to load the library from within the vars folder (I assume it’s in the same repository like the src folder). Simply import the class with a plain import and use it like in plain groovy, e.g.
import org.pack.Myclass
def call() {
def myClass = new MyClass()
}

Representing a class table in Rascal

I would like to represent a kind of class table (CT) as a singleton in Rascal, so that some transformations might refer to the same CT. Since not all transformations need to refer to the CT (and I prefer not to change the signature of the existing transformations), I was wondering if it is possible to implement a kind of singleton object in Rascal.
Is there any recommendation for representing this kind of situation?
Edited: found a solution, though still not sure if this is the idiomatic Rascal approach.
module lang::java::analysis::ClassTable
import Map;
import lang::java::m3::M3Util;
// the class table considered in the source
// code analysis and transformations.
map[str, str] classTable = ();
/**
* Load a class table from a list of JAR files.
* It uses a simple cache mechanism to avoid loading the
* class table each time it is necessary.
*/
map[str, str] loadClassTable(list[loc] jars) {
if(size(classTable) == 0) {
classTable = classesHierarchy(jars);
}
return classTable;
}
Two answers to the question: "what to do if you want to share data acros functions and modules, but not pass the data around as an additional parameter, or as an additional return value?":
a public global variable can hold a reference to a shared data-object like so: public int myGlobalInt = 666; This works for all kinds of (complex) data, including class tables. Use this only if you need shared state of the public variable.
a #memo function is a way to provide fast access to shared data in case you need to share data which will not be modified (i.e. you do not need shared state): #memo int mySharedDataProvider(MyType myArgs) = hardToGetData();. The function's behavior must not have side-effects, i.e. be "functional", and then it will never recompute the return value for earlier provided arguments (instead it will use an internal table to cache previous results).

How to Store Object into Application Level Context in Grails

I want to store HashMap Object likeHashMap<String,MyClass> contextHashMap = new HashMap<String,MyClass> (); which will be accessible through out the application like as we store the object/variables in ApplicationContext of Struts.
So that I can Change or read the Data from this Variable whenever I need.
It isn’t really clear what you need but one option would be to store the data in a singleton service and inject that service wherever it is needed. That is a super simple solution.
You can also create a simple singleton Spring-bean of type Map (ConcurrentHashMap) and also inject into any Grails artefact:
resources.groovy:
beans = {
contextHashMap( ConcurrentHashMap )
}
and inject:
class ExampleController {
def contextHashMap
…
}

Grails 2.5.0 - Cache java object in memory

In bootstrap, I would like to:
Load a list of objects from the database
Extract information from the list of objects
Manipulate the extracted information, creating a new list from the extracted information
Cache the new list
Access the new list at any point after bootstrap has finished running from a controller or service
Is there a plugin to help me do this?
It doesn't look like caching (i.e. temp value, ephemeral, that could be lost at any moment), it's precalculated value. Don't think cache plugin will help.
Basically you need a place to keep this value. It could be anything actually, a static variable from a basic POJO class for example. But if we're talking about Grails I suggest to make a special Service, that will store value, have a method to get it, and probably a method to make initial calculations. Service is a singleton, shared between different artifacts, it will be easy to extend with new logic, refactor and support this code in future. And easier to understand/remember, in contrast to some magical value coming from a cache.
Like:
class SuperValueService {
def value
void refresh() {
value = ...
}
}
Init in bootstrap:
class Bootstrap {
def superValueService
def init { ->
superValueService.refresh()
}
}
and use from controller:
class MyController {
def superValueService
def action() {
render models: [superValue: superValueService.value]
}
}
I'm using compile 'com.google.guava:guava:18.0-rc2' see wiki, which provides also auto-eviction.

Where to put object-cache in Grails?

I want to use some caching from the Guava-library in my Grails app. Is a service class with a non-static field and some getter the best place to put this cache into? Or should it be static or declared somewhere else?
Basic Example:
class TestService {
def getCachedValue(Test test) {
return testCache.get(test)
}
def testCache = new CacheBuilder()
.maximumSize(2000)
.weakKeys()
.weakValues()
.expireAfterWrite(30, TimeUnit.SECONDS)
.build(
new CacheLoader<Test, Date>() {
...
Using a service is the best idea for this. However, making it static is a bit unnecessary since by default services are singletons.
The fact a service is a singleton, and is exposed to not only your controllers but other artifacts within your Grails application make it a perfect fit for accessing an object cache. A single point of access.

Resources