GParse call BackendService async - groovy

I'm trying to implement asynchronism in the backend calls, I've been reading and it seems that GParse is a good library to implement this, but it's not clear to me how i can implement this in a correct way. Can anyone help me? This is my example:
def itemsResults
def locationResults
def itemsNearLocation
GParsPool.withPool {
itemsResults = {searchMyItems()}.async().call()
locationResults = {getLocations()}.async().call()
itemsNearLocation = {getItemsNear(locationResults)}.async().call() // i need locationresults answer in order to call this service
}
model.putAll(["items": itemsResults,
"itemsNearLocation":itemsNearLocation])
return "myView"
So, i need to call 2 apis call and then in the third one i need to use one of the response called async before, and finally add this to my model. How can i achieve this?

You could use GPars dataflows for this... Something like this should work I believe (not tried it though):
import groovyx.gpars.dataflow.Dataflows
import static groovyx.gpars.dataflow.Dataflow.task
final def df = new Dataflows()
task {
df.itemsResults = searchMyItems()
}
task {
df.locationResults = getLocations()
}
task {
df.itemsNearLocation = getItemsNear(df.locationResults)
}
def lastTask = task {
model.putAll(["items": df.itemsResults,
"itemsNearLocation":df.itemsNearLocation])
}
lastTask.join()

Related

How to get a value from inside Anko's async? (KotlIn)

I have a function which uses Anko's async in order to call Google's Distance API and get the distance from one location to another. unfortunately i don't know how to get the data from inside the async and pass it to another function. the code looks something like this
fun getDistance(location1:LatLng,location2:LatLng){
async{
val result = URL(url).readtext()
uithread{
//Parser
//distance value
}
}
}
I'd like to also mention im really new to kotlin or android development in general, please be kind.
There are a number of ways to tackle this; pass an object to the function with your array in it that gets rearranged in your function, or go with something like:
fun getDistance(location1 : LatLng, location2 : LatLng, f: (Long) -> Unit){
doAsync{ // Anko is deprecated as I have been made aware
val result = URL(url).readtext()
val distance : Long = // parse result
uiThread{
f(distance)
}
}
}
and call that with
getDistance(loc1, loc2) { toast("The found distance was $it") }
This is by no means the only way to go; you could update a larger-scoped variable, call a listener, put your lat-longs in a class with updating functions that are called, or a bunch of other ways that I am too lazy to think about :)

SpockExecutionException: Data provider has no data

I've done a bunch of searching and, while I've found a few hits, like Why does Spock think my Data Provider has no data?, none of them seem to be very helpful.
I've only done a data provider a couple of times, but it seems perfect for this. I have the following static method:
static List<ContactPointType> getAddressTypes() {
List<ContactPointType> result = new ArrayList<>();
for (ContactPointType cpType : ContactPointType.values()) {
if (cpType.toString().endsWith("Addr")) {
result.add(cpType);
}
}
return result;
}
And then I'm trying to use it as a data provider for calling a function on my class:
#Unroll("#cpType should be address")
def "isAddress addresses"() {
expect: "isAddress() to be true"
contactPoint.isAddress(cpType)
where:
cpType << getAddressTypes()
}
When I run this, I get:
org.spockframework.runtime.SpockExecutionException: Data provider has no data
at org.spockframework.runtime.JUnitSupervisor.afterFeature(JUnitSupervisor.java:191)
at org.spockframework.runtime.BaseSpecRunner.runFeature(BaseSpecRunner.java:236)
Like I said, it seems pretty straightforward. Does anyone have any ideas?
Well, I've tried the data provider feature and it works as expected:
#Unroll("max(1, #cpType) == #cpType")
class MyFirstSpec extends Specification {
def "let's try this!"() {
expect:
Math.max(1, cpType) == cpType
where:
cpType << dataProvider()
}
List<Integer> dataProvider() {
[2,3,4]
}
}
However if I rewrite the dataProvider function like this, I see the exception that you've mentioned:
List<Integer> dataProvider() {
[] // returns an empty list
}
Yields:
org.spockframework.runtime.SpockExecutionException: Data provider has no data
at org.spockframework.runtime.JUnitSupervisor.afterFeature(JUnitSupervisor.java:180)
at org.spockframework.runtime.BaseSpecRunner.runFeature(BaseSpecRunner.java:239)
So my idea is that probably you end up with an empty list in the data provider implementation and that's why it doesn't work
Another possible (although slightly less realistic idea to be honest) is that you've messed something up with Groovy/Java interconnection
So in terms of resolution to wrap up:
Try to use some more straightforward data provider implementation and test it
If it doesn't work - just define data provider like me in Groovy and re-test

Test the existence of a dynamically chosen class

I have data coming from an external source that I want to process. In order to do that, the objects I'm receiving are tagged with their original class name. Now I want to take that tag name and use it to populate a model in my own application. I'm stuck at the step where I check for that class having an equivalent in my codebase. Its going to look something like this:
this.objects.forEach((object) => {
if (typeof object.class_tag !== 'undefined') { //the problem line
//create class instance
}
});
In php I'd simply call class_exists to achieve this
<?php
if (class_exists($object->class_tag)) {}
What is the correct approach here?
I don't see the clear way to do this in a just one line.
One of the possible approaches is the way you register your existing classes.
For example if you use some kind of a namespace later on you can simply check the class for existance in the namespace.
Sample code:
class A {}
const a = "A"
const namespace = { A };
if (namespace[a]) {
// class exists, you can create object
const instance = new namespace[a]();
}
Probably, much better approach would be to make some service, that will registerClass, checkClass and createInstance for you. So your logic is wrapped in one place.
I found a way of doing it
(credit to https://stackoverflow.com/a/34656123/746549)
let logger = require('../javascripts/serverlog');
let util = require('util');
let Extension = require('../models/object/Extension');
const classes = {Extension: Extension};
/**
* Utility to emulate class exists / dynamic class naming
* #param className
* #returns {*}
*/
module.exports.dynamicClass = (className) => {
logger.debug(classes);
logger.debug(className);
if (classes[className]) {
return classes[className];
} else {
return false;
}
};
Usage:
let ClassOrFalse = dynamicClass.dynamicClass(object._class_tag);

What is the best Scala thread-safe way to write to a BufferedWriter?

I have a simple method that writes a line of data to a File followed by a new line that is executed asynchronously.
def writeToFile(bw: BufferedWriter, str: String) = {
bw.write(str)
bw.newLine
}
When my program runs I'm getting "mixed up" rows in the file due to the async nature of the calls. For instance...say writeToFile(bw, "foo") is executed 3 times asynchronously I may get:
correct output
foo
foo
foo
possible incorrect output
foofoo
foo
I'm able to avoid this possibility by using synchronized method like this:
def writeToFile(bw: BufferedWriter, str: String) = synchronized {
bw.write(str)
bw.newLine
}
From what I researched I can't determine how "safe" this is in regards to scaling my application. The only examples I can find using synchronized is when accessing collections, not writing to a file. My application is built in the Play! Framework 2.4.2.
I personally would create an akka actor for each BufferedWriter what will encapsulate it completely.
import java.io.BufferedWriter
import akka.actor._
import playground.BufferedWriterActor.WriteToBuffer
object BufferedWriterActor {
val name = "BufferedWriterActor"
def props(bw: BufferedWriter) = Props(classOf[BufferedWriterActor], bw)
case class WriteToBuffer(str: String)
}
class BufferedWriterActor(bw: BufferedWriter) extends Actor {
def receive: Actor.Receive = {
case WriteToBuffer(str) =>
bw.write(str)
bw.newLine()
}
}
Use it like this:
import akka.actor.{ActorSystem, Props}
object HelloWorld {
def main(args: Array[String]): Unit = {
val system = ActorSystem("mySystem")
// Share this actor across all your threads.
val myActor = system.actorOf(BufferedWriterActor.props(bw), BufferedWriterActor.name)
// Send messages to this actor from all you threads.
myActor ! BufferedWriterActor.WriteToBuffer("The Text")
}
}
This will chain all calls to this buffer in a single thread.
More info on akka and its actors is here:
http://akka.io/
http://doc.akka.io/docs/akka/snapshot/scala/actors.html
Also play framework itself uses akka so you should be able to use its default ActorSystem, but I do not remember how exactly, sorry.

Groovy - how to use dynamically domain classes static functions

I have list of domain objects which each one of them need to be called as follows:
(<DOMAIN CLASS>.withCriteria {
dataSecurityGroups {
'in' 'id', entitiesIds as Long[]
}
})
The idea is to have this code once, while changing the code a given parameter.
I know that there are several ways to implement it using groovy, and I tried to use them all.
I need to know what is the best practice and short way to do this.
Thanks!
You said you have a List of domain classes so the code below assumes that is true. You don't say what you want to do with the results of each of those queries, so I will assume you have that under control.
You could do something like this...
def listOfDomainClasses = // you have initialized this list somehow...
listOfDomainClasses.each { domainClass ->
def resultForThisClass = domainClass.withCriteria {
dataSecurityGroups {
'in' 'id', entitiesIds as Long[]
}
})
// do something with resultForThisClass
}
I hope that helps.
I'm assuming you are using Grails, since you tagged this question with Gorm. If so, try this:
Class clazz = grailsApplication.domainClasses.find { it.clazz.simpleName == "<DOMAINCLASS>" }.clazz
clazz.withCriteria {
dataSecurityGroups {
'in' 'id', entitiesIds as Long[]
}
}
Or replace grailsApplication.domainClasses and use your list of domain classes instead.
It is not clear what you are really trying to do but maybe what you want is to write a method like this...
/**
* #param someDomainClass A domain class
* #return the results of the query
*/
def myQueryMethod(Class someDomainClass) {
someDomainClass.withCriteria {
dataSecurityGroups {
'in' 'id', entitiesIds as Long[]
}
}
}
Then you can call that method and pass as an argument whatever domain class is appropriate.
Is that the sort of thing you are looking for?

Resources