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.
Related
I need to to read data from database to be read into Config.groovy.
Is that possible to get data from Database into Config.groovy?
No it is not possible. In the sequence of events when a Grails application is starting up the Config.groovy is processed before the Datasource is made available to the application.
Without knowing what you are trying to accomplish I can't make a suggestion on how else to approach this issue.
Updated (based on comment)
In your comment you explain that you are trying to use the feature switch plugin (which is designed to be run time and not persistent). Looking at the source code for the plugin you should be able to make your own service that will load the settings from the database and toggles/updates the feature switch settings. Here is just a simple sketch/example:
package example
import org.springframework.beans.factory.InitializingBean
class MyExampleService implements InitializingBean {
def grailsApplication
void afterPropertiesSet() {
// here is where you would do whatever you needed to load the settings
grailsApplication.config.features['somefeature'].enabled = true
grailsApplication.config.features['otherfeature'].enabled = false
}
}
That should at least give you an idea.
Alternatively you could just write it all in Bootstrap.groovy which can access the datasource/GORM as well.
I am a newbie to Grails and still learning the ropes! The application that i work on uses services.
My task is to add a new method in one of the services and have it get called from clients.
This new method is going to be pretty long and i don't want all the method body to be in the service class.
I would like to add another method in a place other than this service to do all the calculations for this new method.
Which is the best place to add a method like that? Should i add a new domain? Or just a controller class?
I don't want any of the information in the new method to be saved to database.
A sample code look like this:
class MyService {
String getDomainName(String ID) {
return domainNameGenerator(ID);
}
}
Now i want to put the domainNameGenerator method into another place.
Place your standalone code in src/groovy or src/java depending on the actual language of your code, but there's nothing wrong with putting code in the service class itself. If the new class and the service package is the same, you don't even have to add an import.
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.
In Grails i am using custom tag library, here is my code
def isCheck = { attrs, body ->
def checkUser = springSecurityService.currentUser
def owner = attrs?.owner
if(checkUser?.id == owner?.id) {
out << body()
}
}
But here how the out object work.I think its from TagLibraryApi class.But without any initialization how it's work.
can anyone give me the concept for using out object.
From the Grails docs:
there is an implicit out variable that refers to the output Writer which you can use to append content to the response
Think of it like a field from a super class that you are referencing.
In this context out refers to the output stream/writer. Typically this is going to be the GroovyPage from which it's called.
As far as using it, I'm not sure what you are looking for but your example is pretty complete. You can always browse the source code for the built in tags for Grails on Github.
I'm building a grails app and have come across an issue when trying to instatiate a service, in a different service. Both of the services use a method defined in the other eg.
class fooService{
def barService
barService.doIt()
def getIt(){
...
}
}
class barService{
def fooService
fooService.getIt()
def doIt(){
...
}
}
When I run the app and go to where the methods are used, it brings up this error;
Error creating bean with name 'fooService':
org.springframework.beans.factory.FactoryBeanNotInitializedException: FactoryBean is
not fully initialized yet
Is this something that cannot be done in grails? Or could anyone offer any advice?
Thanks
I've had similar issues in the past, but only when both services are transactional. If it's possible to make at least one of them non-transactional then it should work as-is. If that's not possible then the fallback is to do a kind of "late binding"
class FooService {
def grailsApplication
private getBarService() {
grailsApplication.mainContext.barService
}
public methodThatUsesBarService() {
barService.doSomething()
}
}
This will look up barService in the app context at the point where it is used, rather than at the point where the FooService is created.
Service can be called by another service but not possible at time of initialization. If you want to implement this, the way should be like.
class fooService{
def barService
def getIt(){
...
}
def anotherFooMethod(){
barService.doIt();
}
}
class barService{
def fooService
def doIt(){
...
}
def anotherBarMethod(){
fooService.getIt();
}
}
All these answers are excellent and show how to handle the problem through the framework. Although, when I had this problem I realized there must be a flaw in my plan and architecture if I absolutely must have services calling each other and causing conflicts. Instead of finding a work-around I took a slightly less complicated and strait forward approach -- I restructured. I moved the offending methods from the service class into another service class. It took some refactoring, rethinking and copy/paste skills but I think the application is better for it.
I'm not saying this is better than the other answers. I'm saying, this time, with this project refactoring was a better, faster, less complicated solution. I highly recommend it.
UPDATE
Our final strategy is to refactor all "utility" service functions into a baseService class then have all other services that need the utility services extend baseService. The new policy is to avoid injecting services into other services, unless some situation arises that doesn't allow us to follow this inheritance pattern. This will give us a cleaner code base and less of a spaghetti trail of injections to follow. Plus, it eliminates the emergence of this error.
That's not valid code, so it's hard to know what's really going on. Are the doIt() and getIt() calls in constructors? If so, change the services to implement org.springframework.beans.factory.InitializingBean and do the calls in the afterPropertiesSet method.
You can handle the circular reference using the following -
Lets call it firstSerivce and secondService.
Code changes for secondService class
protected def firstService
def grailsApplication
def initialize() {
this.firstService = grailsApplication.mainContext.firstService
}
code changes in Bootstrap.groovy
def secondService
def init = { servletContext ->
secondService.initialize()
...
..