1

I have been running into a consistent problem using the LBAPI which I feel is probably a common use case given its purpose. I am generating a chart which uses LBAPI snapshots of a group of Portfolio Items to calculate the chart series. I know the minimum and maximum snapshot dates, and need to query once a day in between these two dates. There are two main ways I have found to accomplish this, both of which are not ideal:

  • Use the _ValidFrom and _ValidTo filter properties to limit the results to snapshots within the selected timeframe. This is bad because it will also load snapshots which I don't particularly care about. For instance if a PI is revised several times throughout the day, I'm really only concerned with the last valid snapshot of that day. Because some of the PIs I'm looking for have been revised several thousand times, this method requires pulling mostly data I'm not interested in, which results in unnecessarily long load times.

  • Use the __At filter property and send a separate request for each query date. This method is not ideal because some charts would require several hundred requests, with many requests returning redundant results. For example if a PI wasn't modified for several days, each request within that time frame would return a separate instance of the same snapshot.

My workaround for this was to simulate the effect of __At, but with several filters per request. To do this, I added this filter to my request:

Rally.data.lookback.QueryFilter.or(_.map(queryDates, function(queryDate) {
    return Rally.data.lookback.QueryFilter.and([{
        property : '_ValidFrom',
        operator : '<=',
        value    : queryDate
    },{
        property : '_ValidTo',
        operator : '>=',
        value    : queryDate
    }]);
}))

But of course, a new problem arises... Adding this filter results in much too large of a request to be sent via the LBAPI, unless querying for less than ~20 dates. Is there a way I can send larger filters to the LBAPI? Or will I need to break theis up into several requests, which only makes this solution slightly better than the second of the latter.

Any help would be much appreciated. Thanks!

Conner Reeves
  • 1,381
  • 8
  • 13

1 Answers1

2

Conner, my recommendation is to download all of the snapshots even the ones you don't want and marshal them on the client side. There is functionality in the Lumenize library that's bundled with the App SDK that makes this relatively easy and the TimeSeriesCalculator will also accomplish this for you with even more features like aggregating the data into series.

Larry Maccherone
  • 9,393
  • 3
  • 27
  • 43
  • Hey Larry. This is the method I'm currently using, but there are a few edge cases that result in queries which take several minutes to come back. For instance if I need all the snapshots for child PIs below a PI with several hundred children, each of which has several hundred revisions. It works, it just takes quite a while and seems like something that could be optimized. It would be really awesome if I could provide an array of "__At" filters, ORed together. Thanks for the response! – Conner Reeves Mar 21 '14 at 16:07
  • The array of __At filters approach is under consideration. Another alternative that we're also exploring is server-side cached/incrementally-updated aggregations. Imagine some derivative of the Lumenize [TimeSeriesCalculator API](http://commondatastorage.googleapis.com/versions.lumenize.com/docs/Lumenize-docs/index.html#!/api/Lumenize.TimeSeriesCalculator) that stays up to date as more snapshots are added and where you only stream the aggregations client side. – Larry Maccherone Mar 22 '14 at 15:40
  • Conner, re: the 'too large request'...if you're using the SnapshotStore, it has a 'useHttpPost' property that, if set to true, will (obviously) make the sdk use POST to allow you to send larger requests. – Joel Sherriff Mar 24 '14 at 13:15
  • Hey Joel, this sounds like exactly what I need! Unfortunately, I tried adding the property you mentioned and it would appear the request is still processing as 'GET'. I am using RC2 of the SDK and couldn't find any documentation for the 'useHttpPost' property. Any ideas? – Conner Reeves Mar 24 '14 at 16:34