Martin Anderson - threads v actors
-
Upload
bloodredsun -
Category
Technology
-
view
1.412 -
download
4
description
Transcript of Martin Anderson - threads v actors
![Page 1: Martin Anderson - threads v actors](https://reader034.fdocuments.net/reader034/viewer/2022042714/554bbb0ab4c9053a298b4d06/html5/thumbnails/1.jpg)
LIGHTNING TALK REPLACING THREADS WITH ACTORS FOR CONCURRENT WEB APPLICATION SERVICE CALLS Martin Anderson LJC Open Conference 2011
![Page 2: Martin Anderson - threads v actors](https://reader034.fdocuments.net/reader034/viewer/2022042714/554bbb0ab4c9053a298b4d06/html5/thumbnails/2.jpg)
CONCURRENT SERVICE CALLS
• Most web pages need data from multiple sources
• Scatter/Gather approach to perform all the service calls in parallel then rendering the responses
2
![Page 3: Martin Anderson - threads v actors](https://reader034.fdocuments.net/reader034/viewer/2022042714/554bbb0ab4c9053a298b4d06/html5/thumbnails/3.jpg)
CONCURRENCY MODEL
dispatch service calls
controller’s job done
rendering starts early
3
![Page 4: Martin Anderson - threads v actors](https://reader034.fdocuments.net/reader034/viewer/2022042714/554bbb0ab4c9053a298b4d06/html5/thumbnails/4.jpg)
THREADS
• Well understood (if not always well implemented!)
• java.util.concurrent library eases the pain • Resource usage?
4
![Page 5: Martin Anderson - threads v actors](https://reader034.fdocuments.net/reader034/viewer/2022042714/554bbb0ab4c9053a298b4d06/html5/thumbnails/5.jpg)
ACTORS
• Been around since 1973 • Erlang popularised usage • Actor library for Java? Akka! • Most strongly associated with Scala but
has a Java API
5
![Page 6: Martin Anderson - threads v actors](https://reader034.fdocuments.net/reader034/viewer/2022042714/554bbb0ab4c9053a298b4d06/html5/thumbnails/6.jpg)
USING AN EXECUTOR SERVICE IN A SERVLET
public void doGet(HttpServletRequest request, HttpServletResponse response) throws…{
List<MyServiceCallable> myServiceCallables = new ArrayList<MyServiceCallable>();
for (int ii = 0; ii < 10; ii++) { myServiceCallables.add(new MyServiceCallablle(remoteClient)); }
List<Future<String>> futures = executorService.invokeAll(myServiceCallables);
… for (Future future : futures) { writer.write( future.get() ); }
… }
6
![Page 7: Martin Anderson - threads v actors](https://reader034.fdocuments.net/reader034/viewer/2022042714/554bbb0ab4c9053a298b4d06/html5/thumbnails/7.jpg)
USING AKKA ACTORS IN A SERVLET
public void doGet(HttpServletRequest request, HttpServletResponse response) throws…{
Works works = new Works(); for (int ii = 0; ii < 10; ii++) {
works.add(new Work())); } masterActor.tell(works);
List<Future<String>> futures = works.getFutures();
… for (Future future : futures) { writer.write( future.get() ); }
… }
7
![Page 8: Martin Anderson - threads v actors](https://reader034.fdocuments.net/reader034/viewer/2022042714/554bbb0ab4c9053a298b4d06/html5/thumbnails/8.jpg)
SO WHAT’S IN AN ACTOR 1?
public class MasterActor extends UntypedActor { private ActorRef router; static class LoadBalancer extends UntypedLoadBalancer { private final InfiniteIterator<ActorRef> workers; public LoadBalancer(ActorRef[] workers) { this.workers =
new CyclicIterator<ActorRef>(asList(workers)); } public InfiniteIterator<ActorRef> seq() { return workers; } }
8
![Page 9: Martin Anderson - threads v actors](https://reader034.fdocuments.net/reader034/viewer/2022042714/554bbb0ab4c9053a298b4d06/html5/thumbnails/9.jpg)
SO WHAT’S IN AN ACTOR 2?
public MasterActor(final int numWorkers, final RemoteClient remoteClient) { // create an array of started workers final ActorRef[] workers = new ActorRef[numWorkers]; for (int i = 0; i < numWorkers; i++) { workers[i] = actorOf( new UntypedActorFactory() { public UntypedActor create() { return new WorkerActor(remoteClient); } }) .start(); } // wrap all the workers with a load-balancing router router = actorOf(new UntypedActorFactory() { public UntypedActor create() { return new LoadBalancer(workers); } }).start(); }
9
![Page 10: Martin Anderson - threads v actors](https://reader034.fdocuments.net/reader034/viewer/2022042714/554bbb0ab4c9053a298b4d06/html5/thumbnails/10.jpg)
SO WHAT’S IN AN ACTOR 3?
// message handler in MasterActor public void onReceive(Object message) { if (message instanceof Works) { for (Work work : ((Works) message).getAll()) { router.tell(work); } } }
10
![Page 11: Martin Anderson - threads v actors](https://reader034.fdocuments.net/reader034/viewer/2022042714/554bbb0ab4c9053a298b4d06/html5/thumbnails/11.jpg)
SO WHAT’S IN AN ACTOR 4?
public class WorkerActor extends UntypedActor { RemoteClient remoteClient; public WorkerActor(RemoteClient remoteClient) { this.remoteClient = remoteClient; } @Override public void onReceive(Object message) throws Exception { if (message instanceof Work) { Work work = (Work) message; remoteClient.execute(work); } } }
11
![Page 12: Martin Anderson - threads v actors](https://reader034.fdocuments.net/reader034/viewer/2022042714/554bbb0ab4c9053a298b4d06/html5/thumbnails/12.jpg)
SO WHAT’S IN OUR REMOTECLIENT?
public void execute(final Work work) throws IOException {
ContentExchange exchange = new ContentExchange() { protected void onResponseComplete() throws IOException {
super.onResponseComplete(); String responseContent = this.getResponseContent(); work.setFutureResponse(responseContent); } }; //set the method and the url exchange.setMethod("GET"); exchange.setURL(work.getUrl()); // start the exchange httpClient.send(exchange);
}
12
![Page 13: Martin Anderson - threads v actors](https://reader034.fdocuments.net/reader034/viewer/2022042714/554bbb0ab4c9053a298b4d06/html5/thumbnails/13.jpg)
SO WHY USE AKKA/ACTORS
• More resource efficient for certain jobs • Easier for mere mortals to reason with • Nested supervisors can restart failed actors • Supports STM if required
13
![Page 14: Martin Anderson - threads v actors](https://reader034.fdocuments.net/reader034/viewer/2022042714/554bbb0ab4c9053a298b4d06/html5/thumbnails/14.jpg)
THANK YOU
https://github.com/bloodredsun/ConcurrentWebAppExample
Email: [email protected] Twitter: @mdjanderson Blog: http://bloodredsun.com/ Betfair Blog: http://views.betfair.com/
14