Akka Http caching metrics - scala

I'm using Akka HTTP caching and I would love to add some metrics like cache hit/miss to understand how's my cache doing.
I'm reading this documentation on Akka HTTP Caching. However I'm not seeing anywhere if their cache supports metrics.
I'm using the getOrLoad method. Am I missing something or it's just the fact that they don't do any metrics for this library?

I didn't see anything in Akka documentation either but if you are using the Caffeine implementation you could maybe have access to Caffeine methods and enable statistics.
Caffeine statistics documentation: https://github.com/ben-manes/caffeine/wiki/Statistics
Obviously, you would not anymore be agnostic of the caching library.

Related

Is there any blocking web service API in Play 2?

According to the documentation, the Play 2.3 WS API is async. However, I need a blocking WS client to access external web service.
Is there any blocking WS API in Play 2.3? Or do I have to refer to primitive scala API?
You could force it probably using something like Await.result(Future.successful("FOO")) but please check first if you really need to block. In most (almost all) cases you don't have to. Because if you block within asynchronous code you're throwing all advantages brought to you by that overboard.
It might be a good idea to refactor your code base to handle things asynchronous which is a bit challenging if done for the first time but it definitely pays off.

Are Retrofit and OkHttp suitable for Java EE/Server-side use?

I like the APIs of the Retrofit and OkHttp rest/http libraries from Square. I am evaluating options for writing a server-side rest client. For each request to my SOAP-based web service, I have to consume another, restful web service, thus my need for a rest client.
My question is, are Retrofit and OkHttp suitable for server-side use in a highly concurrent web app, or are there likely to be issues, known or otherwise, stemming from these APIs having been designed for use primarily outside of the server-side?
Reading the documentation and perusing the code, nothing jumped out at me to indicate that these libraries would not be suitable. But I don't want to be a guinea pig either. Has anyone experienced any issues with server-side use under high load/concurrency? Had success? Anyone from the dev teams for those libraries care to comment? ;)
We use OkHttp on the Square Cash server and we haven't had problems.
Some of the default settings are not suitable for server side usage, for example, the maximum number of concurrent requests per host defaults to 5.
There is some discussion on this at https://github.com/square/okhttp/issues/4354.
In the microservices architecture world (using Spring Framework), Retrofit/Okhttp may not be a good fit as a REST client for inter-service communication. Using WebClient/RestTemplate will have at least the below advantages over using retrofit for the same purpose:
RestTemplate/WebClient can be easily configured to make use of client-side load balancing (Ribbon), thereby requests can be rotated among various instances or another microservice.
Hystrix can be easily configured with RestTemplate, thereby increasing the fault tolerance (circuit breaker pattern) of the overall system w.r.t inter-service communication.
Service discovery can be easily configured using Eureka or Consul, thereby the client need not know the host/port/protocol of the target web service. All we need is to enable the discovery client.
Alternatively, you can also explore Feign, which is a declarative web service client similar to retrofit, but with all the advantages of RestTemplate.
You can also have a loot at the following article:
https://www.javacodemonk.com/retrofit-vs-feignclient-on-server-side-with-spring-cloud-d7f199c4

spray.io http server inside Play2 application context

I have an API service implemented in a Play 2 App, Currently the api handles 5-7000 requests per second on 5 servers. I have benchmarked Spray.IO and Play2 recently and see almost 3x the performance on simple http requests.
I would prefer not to re-implement everything in Spray, if instead I can somehow embed the spray HTTP server in my Play app, than use that to server http requests.
Is this possible? and is there an example of this out there?
I can say that Spray actually is the fastest JVM-based toolkit for web-based development, you can check out the latest benchmarks on the official blog.
As for the question. If you want to write your own implementation for a little HTTP server then you should check spray-can http based api, spray-io is just a layer between Akka IO and Java NIO. I'm not very good at Play, but as a way i would sugest to create a multi-build sbt config or separate project with Spray http server and connect them through REST api.
Architecture would be pretty simple cause it's based on Akka actors in the simplest case would look like a bunch of cases in the receive method:
def receive = {
case HttpRequest(GET, Uri.Path("/ping"), _, _, _) =>
sender ! HttpResponse(entity = "PONG")
}
On the Play side you should use Akka or Play's routing file for describing routes.
Also check out Spray routing api. It's much easier to implement and to use and looks very similar to what Spray can give you with route file, but more flexible and readable.
Also Spray has many great very detailed examples on their Github repo: spray-can and spray-routing.
BTW Spray team also made available Play template engine for front-end and called it Twirl so porting your application to Spray won't take much time
We see that Play rates well for a full stack framework:
http://www.techempower.com/benchmarks/#section=data-r6&hw=i7&test=db&c=1&d=2&a=1
We see that there are trade-offs in terms of developer productivity i.e. the faster you want to go, the less productive your developers will typically be. You need to know whether Play will achieve the performance that your application demands.
Incidentally we have been focused and continue to focus on improving Play's performance.
I hope that this helps.
Actually, The Play framework will soon be using Spray I/O for it's http serverices.
So it looks like you'll be able to have the best of both worlds!

Adapter Proxy for Restful APIs

this is a general 'what technologies are available' question.
My company provides a web application with a RESTful API. However, it is too slow for my needs and some of the results are in an awkward format.
I want to wrap their restful server with a proxy/adapter server, so when you connect to the proxy you get the RESTful API I wish the real one provides.
So it needs to do a few things:
passthrough most requests
cache some requests
do some extra requests on the original server to detect if a request is cacheable
for instance: there is a request for a field in a record: GET /records/id/field which might be slow, but there is a fingerprint request GET /records/id/fingerprint which is always fast. If there exists a cache of GET /records/1/field2 for the fingerprint feedbeef, then I need to check the original server still has the fingerprint feed beef before serving the cached version.
fix headers for some responses - e.g. content-type, based upon the path
do stream processing on some large content, for instance
GET /records/id/attachments/1234
returns a 100Mb log file in text format
remove null characters from files
optionally recode the log to filter out irrelevant lines, reducing the load on the client
cache the filtered version for later requests.
While I could modify the client to achieve this functionality, such code would not be re-usable for other clients (different languages), and complicates the client logic.
I had a look at whether clojure/ring could do it, and while there is a nice little proxy middleware for it, it doesn't handle streaming content as far as I can tell - the whole 100Mb would have to be downloaded. Also it doesn't include any cache logic yet.
I took a look at whether squid could do it, but I'm not familiar with the technology, and it seems mostly concerned with passing through requests rather than modifying them on the fly.
I'm looking for hints where I might find the correct technology to implement this. I'm mostly language agnostic if learning a new language gets me access to a really simple way to do it.
I believe you should choose a platform that is easier for you to implement your custom business logic on. The following web application frameworks provide easy connectivity with REST APIs, and allow you to create a web application that could work as a REST proxy:
Play framework (Java + Scala)
express + Node.js (Javascript)
Sinatra (Ruby)
I'm more familiar with Play, of which I know it provides utilities for caching you could find useful, and is also extendable by a number of plugins.
If you are familiar with Scala, you could have a also have a look at Finagle. It is a framework build be Twitter's infrastructure team to provide protocol-agnostic connectivity. It might be an overkill for REST to REST proxy, but it provides abstractions you might find useful.
You could also look at some 3rd party services like Apitools, which allows to create a proxy programmatically (in lua). Apirise is a similar service (of which I'm a co-founder) that intends to do provide similar functionalities with a user-friendly UI.
Beeceptor does exactly what you want. It plugs in-between your web-app and original API to route requests.
For your use-case of caching a few responses, you can create a rule. That way it shall not hit the original endpoint.
The requests to original APIs can be mocked, and you can inspect response
You can simulate delays.
(Note: it is a shameless plug, I am the author of Beeceptor and thought it should help you and other developers.)
https://github.com/nodejitsu/node-http-proxy is looking useful - although I don't yet know if it can stream process for transcoding.

using REST webservices as a datasource for Lift?

Is there a way to use a webservice (REST in this case) as the data source for a Lift application? I can find a number of tutorials/examples of using Lift to provide the REST API, but in my case the data is hosted elsewhere and exported as a REST webservice. Pointers to doc are greatly appreciated.
Thanks,
Jeff
This is not related to Lift in fact. There is a lot of different pieces of information already:
HttpClient library as was suggested already,
or Dispatch Scala library for accessing HTTP services
information on how to cache data in Scala in various ways in case you need it
Think about caching thoroughly, it is generally a good choice if your application generates a lot of requests and you can afford caching. Caching will let you achieve many goals:
decrease response time, as you do not depend on the remote service (if you do synchronous data processing)
avoid Denial of Service in case the remote service dies. Otherwise your application will generate many sockets to read data and exhaust resources (either sockets or threads or something else)
do not exceed SLA of the remote service, as many services constrain the number of requests you are allowed to pefrorm per some unit of time.
So you can just sit and put these things together, that's it.
If you really want to be fancy, you can create a Record implementation for a REST-based data source. There's already one of these in existence that works with CouchDB. Using the lift-couchdb module, the interactions with CouchDB are abstracted away and all you deal with is the Scala code. There is a short wiki page with instructions on how to get started with lift-couchdb here:
http://www.assembla.com/wiki/show/liftweb/CouchDB
The pertinent source code files are available here:
http://github.com/lift/lift/tree/master/framework/lift-persistence/lift-couchdb/src/main/scala/net/liftweb/couchdb/
Using the Record interface gives you access to lots of Traits which you use to provide functionality with minimal code-writing such as creating HTML forms, providing lifecycle based calls, and easy hooks for validation.
I've put a scala layer over HttpClient and then use that. I've been meaning to put this on github for some time.
I use Dispatch (which is a wrapper around HttpClient) for making REST calls. Looks nice and simple