+ All Categories
Home > Technology > Martin Anderson - threads v actors

Martin Anderson - threads v actors

Date post: 08-May-2015
Category:
Upload: bloodredsun
View: 1,411 times
Download: 4 times
Share this document with a friend
Description:
Slides from my lightning presentation from the London Java Community Open Conference Nov 2011
14
LIGHTNING TALK REPLACING THREADS WITH ACTORS FOR CONCURRENT WEB APPLICATION SERVICE CALLS Martin Anderson LJC Open Conference 2011
Transcript
Page 1: Martin Anderson - threads v actors

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

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

CONCURRENCY MODEL

dispatch service calls

controller’s job done

rendering starts early

3

Page 4: Martin Anderson - threads v actors

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

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

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

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

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

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

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

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

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

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

THANK YOU

https://github.com/bloodredsun/ConcurrentWebAppExample

Email: [email protected] Twitter: @mdjanderson Blog: http://bloodredsun.com/ Betfair Blog: http://views.betfair.com/

14


Recommended