Call a non instance function from a metric

#1

I’ve a type Awesome on which I have a non member functions. My type definition in Awesome.c3typ is something like this:

type Awesome {
  getSomeAwesomeness:       function(Awesome): decimal js server
}

The function is defined in Awesome.js as follows:

function getSomeAwesomeness(awesome) {
  return ...;
}

I also have another type ParentType that is related to the previous one as follows:

type ParentType {
  awesomes: [Awesome](parent)
}

I want to define an aggregation on ParentType that calls getSomeAwesomeness on every Awesome related to the parent. How can I call this non instance function on my Awesome instances?

{
  id: "Awesomeness_AGG", 
  name: "Awesomeness_AGG", 
  srcType: "ParentType", 
  path: "awesomes",
  tsDecl: {
    data: "Awesome.getSomeAwesomeness(...)", 
    treatment: "SUM"
  }
}
0 Likes

#2

It seems there is a keyword self that can be passed to the method call!

0 Likes

#3

you can keep the data field as self or you can chose to have no path and the data field can be “awesomes” directly

0 Likes

#4

Is this correct?

{
  id: "Awesomeness_AGG", 
  name: "Awesomeness_AGG", 
  srcType: "ParentType", 
  path: "awesomes",
  tsDecl: {
    data: "Awesome.getSomeAwesomeness(self)", 
    treatment: "SUM"
  }
}
0 Likes

#6

you cannot call a custom action via a tsDecl based metric. If you want to call a custom action then you will have to convert it to an actionDecl metric

0 Likes

#7

Oh didn’t know about this one! So my metric should be like this:

{
  "id" : "Awesomeness_AGG",
  "name" : "Awesomeness_AGG",
  "srcType" : "ParentType",
  "path" : "awesomes",
  "actionDecl" : {
    "action" : "Awesome.getSomeAwesomeness(self)"
  }
}

Or I create another function Awesome.getSomeAwesomenessFromSet that accepts a collection of Awesome instances and have my metric looks like:

{
  "id" : "Awesomeness_AGG",
  "name" : "Awesomeness_AGG",
  "srcType" : "ParentType",
  "actionDecl" : {
    "action" : "Awesome.getSomeAwesomeness(awesomes)"
  }
}
0 Likes

#8
type ParentType {
  awesomes: [Awesome](parent)

  getSomeAwesomeness:       function(objs: [Awesome]): Timeseries js server
}

{
  "id" : "Awesomeness_AGG",
  "name" : "Awesomeness_AGG",
  "srcType" : "ParentType",
  "actionDecl" : {
    "action" : "getSomeAwesomeness",
   "include":"awesomes"
  }
}

The action (method) has to be on the srcType. you can pass all the objs together and then compute what you need to for the parent.

1 Like

#10

@rohit.sureka looking at the type definition of ActionMetricDecl, it seems I cannot call my function as you described earlier!
in fact the function in action need to have this exact signature

function(Obj obj, TSEvalSpec spec, SimpleMetric metric) : Timeseries

Otherwise I will get this error:

c3.love.exceptions.C3RuntimeException: c3.love.exceptions.C3RuntimeException: MetricEngine error : c3.love.exceptions.C3RuntimeException: Error java.lang.IllegalStateException: key: obj is not defined as a parameter
0 Likes