Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

App scala

562 views

Published on

Simple introdution to scala concurrence with actors and functional parts

Published in: Technology
  • Be the first to comment

App scala

  1. 1. Por que gosto de scala? CodeSimples.com
  2. 2. http://www.erlang-factory.com/upload/presentations/395/ErlangandFirst-PersonShooters.pdf
  3. 3. Hoje somente os “porquês” nada de “como”.
  4. 4. Definições (Meramente para este contexto)ConcorrênciaProgramas de rodam em paralelo compartilhando recursos de memória, io eprocessamento.ParalelismoProgramas que não compartilham memória, io e processamento.Programação imperativaNa Ciência da Computação, programação imperativa é um paradigma deprogramação que descreve a computação como ações, enunciados oucomandos que mudam o estado (variáveis) de um programa. Muito parecidocom o comportamento imperativo das linguagens naturais que expressamordens, programas imperativos são uma sequência de comandos para ocomputador executar.Programação funcionalEm ciência da computação, programação funcional é um paradigma deprogramação que trata a computação como uma avaliação de funçõesmatemáticas e que evita estados ou dados mutáveis. Ela enfatiza a aplicaçãode funções, em contraste da programação imperativa, que enfatiza mudançasno estado do programa.
  5. 5. Desenvolvimento de aplicações concorrentesProgramação imperativa
  6. 6. Starvation e Deadlocks Locado Print Office Executando Find Game Games Add new GameKiosk Print Office Locado Kiosk Executando Game Take tickets Add tickets
  7. 7. Race Conditions public class RaceCondition { private static boolean done; public static void main(final String[] args) throws InterruptedException { new Thread( new Runnable() { public void run() { int i = 0; while(!done) { i++; } System.out.println("Done!"); } } ).start(); System.out.println("OS:" + System.getProperty("os.name")); Thread.sleep(2000); done = true; System.out.println("flag done set to true"); } }
  8. 8. Fixed Race Conditions public class RaceCondition { private static volatile boolean done; public static void main(final String[] args) throws InterruptedException { new Thread( new Runnable() { public void run() { int i = 0; while(!done) { i++; } System.out.println("Done!"); } } ).start(); System.out.println("OS:" + System.getProperty("os.name")); Thread.sleep(2000); done = true; System.out.println("flag done set to true"); } }
  9. 9. Fixed Race ConditionsBásicamente, volatile é usada para indicar que o valor da variável pode ser modificada por outras Threads.Isso quer dizer que:O valor da variável não será cacheado pela thread local, todas as leituras e escritas serão feitas na memóriaprincipalO acesso a variáveis age como se estivesse incluído em um bloco sincronizado.
  10. 10. Complexibilidade acidental sem limites...public class Account implements Comparable<Account> { private int balance; public final Lock monitor = new ReentrantLock(); public Account(final int initialBalance) { balance = initialBalance; } public int compareTo(final Account other) { return new Integer(hashCode()).compareTo(other.hashCode()); } public void deposit(final int amount) { monitor.lock(); try { if (amount > 0) balance += amount; } finally { monitor.unlock(); } } public boolean withdraw(final int amount) { try { monitor.lock(); if (amount > 0 && balance >= amount) { balance -= amount; return true; } return false; } finally { monitor.unlock(); } }}
  11. 11. Fault toleranceO que fazer quando acontece um erro dentro de umconjunto de threads ou em uma thread que pertence a umconjunto?Escrever o código para esse tipo de tratamento ecomplexo.Talvez somente estamos adicionando maiscomplexibilidade e novos pontos de falha do querealmente tratando o problema.
  12. 12. Scale up / Scale out
  13. 13. Scale up / Scale outThread e um recurso muito caro, se vc quer atender muitos usuários. public class DieLikeADog { private static Object s = new Object(); private static int count = 0; public static void main(String[] argv){ for(;;){ new Thread(new Runnable(){ public void run(){ synchronized(s){ count += 1; System.err.println("New thread #"+count); } for(;;){ try { Thread.sleep(1000); } catch (Exception e){ System.err.println(e); } } } }).start(); } } }
  14. 14. Desenvolvimento de aplicações concorrentesProgramação imperativa com aspectos funcionais
  15. 15. Clean codeobject CityController extends Controller { val cityMapping = ( "name" -> nonEmptyText ) val cityForm = Form( mapping ( "name" -> nonEmptyText, "province" -> nonEmptyText ) ( (name:String, province:String) => City(Map[String, AnyRef]("name" -> name, "province" -> province)) ) ( (city:City) => Some((city.name, city.province)) ) ) def index = Action { implicit request => val cities = Prevayler.system.executeQuery( FindAllCities() ) Ok(views.html.nereida.city.index(cities)); } def build = Action { Ok(views.html.nereida.city.build(cityForm, Seq[String]("Parana", "Bahia"))); } def create = processJSONRequest { implicit json => { val city = Prevayler.system.executeTransaction( AddNewCity(json) ) Created(Json.toJson(city)) } } def show(id:String) = processQuery { Prevayler.system.executeQuery( FindCityById(id) ) }….
  16. 16. Clean code... def edit(id:String) = processQuery { Prevayler.system.executeQuery( FindCityById(id) ) } def update(id:String) = processJSONRequest { implicit json => { val city = Prevayler.system.executeTransaction( UpdateCity(id, json) ) Created(Json.toJson(city)) } } def destroy(id:String) = Action { implicit request => val city = Prevayler.system.executeTransaction( DeleteCity(id) ) Ok(Json.toJson(city)) }….
  17. 17. Clean code... //aux functions def processJSONRequest(innerFunction: JsValue => Result) = { Action { implicit request => { Form(cityMapping).bindFromRequest.fold( errors => BadRequest(errors.errorsAsJson), value => { request.body.asJson.map { json => innerFunction(json) }.getOrElse { BadRequest(Json.toJson(Map("error" -> "invalid json"))) } } ) } } } def processQuery(innerFunction: => Option[City]) = { Action { innerFunction.map { city => Ok(views.html.nereida.city.build(cityForm.fill( city ), Seq[String]("Parana","Bahia"))) }.getOrElse { BadRequest(Json.toJson(Map("error" -> "invalid json"))) } } }}
  18. 18. No shared state...case class City(state:Map[String, AnyRef]) { def name: String = state.getOrElse("name","").asInstanceOf[String] def province: String = state.getOrElse("province","").asInstanceOf[String] def id: String = state.getOrElse("_id","").toString}
  19. 19. No shared state….trait ManageCities { def addCity(city:City):City = { val newState = city.state + ("_id" -> new ObjectId()) citiesCollection += newState City(newState) } def cities():List[City] = { val list:ArrayBuffer[City] = new ArrayBuffer[City](); citiesCollection.find.foreach { cada => println(cada) list += City(cada) } list.toList } def findCityById(id:String):Option[City] = { citiesCollection.findOneByID(id).map { city => Some[City](City(city)) }.getOrElse { Some[City](null) } }….
  20. 20. No shared state…. def removeCityById(id:String):Option[City] = { findCityById(id).map { city => citiesCollection.remove(city.state) Some(city) }.getOrElse { Some[City](null) } } def updateCityById(id:String, name:String):Option[City] = { findCityById(id).map { city => city.state.put("name", name) citiesCollection.save(city.state) Some(city) }.getOrElse { Some[City](null) } } def mongoConnection(): MongoConnection = MongoConnection("localhost", 39717) def mongoDB(): MongoDB = mongoConnection()("nereida") def citiesCollection(): MongoCollection = mongoDB()("cities") implicit def dbObjectToMap(dbObject:DBObject): Map[String,AnyRef] = { (dbObject.toMap.asInstanceOf[java.util.Map[String,AnyRef]]).toMap } implicit def map2DBObject(state:Map[String,AnyRef]): DBObject = { MongoDBObject(state.toList).asDBObject }}
  21. 21. Actors (Scala 2.10 unificará com implementação do akka 2.0)import akka.actor.Actorimport akka.actor.Propsimport akka.event.Loggingclass MyActor extends Actor { val log = Logging(context.system, this) def receive = { case "test" ⇒ log.info("received test") case _ ⇒ log.info("received unknown message") }}object Main extends App { val system = ActorSystem("MySystem") val myActor = system.actorOf(Props[MyActor], name = "myactor") myActor ! “test”}
  22. 22. Pattern Matchingobject MatchTest1 extends Application { def matchTest(x: Int): String = x match { case 1 => "one" case 2 => "two" case _ => "many" } println(matchTest(3))}Nada impede o uso de estrategias antes ou depois do matching.Eu prefiro depois.
  23. 23. Software Transactional MemoryUm STM transforma o heap do Java em uma base de dados transacional onde e possível iniciaruma transacao begin/commit/rollback .Muito parecido com banco de dados regulares.Ela implementa as três primeiras letras contidas em ACID, ou seja- Atomicidade- Consistência- Isolamento
  24. 24. Message passing approach Actor message Address Mailbox Another Actor Pode existir ou não. Se não existir entra em ação o sistema de tratamento de falhas
  25. 25. Fault Tolerance - “let it crash” Exit signal Sistema cai com um erro
  26. 26. Fault Tolerance com supervisores - “let it crash” Exit signal SupervisorSupervsores identificam a falha e decidem por:- Reiniciar o processamento- Reiniciar o ator- Reiniciar o sub-sistema.
  27. 27. Scale up / Scale out
  28. 28. Scale up / Scale outUm MessageDispatcher Akka é o que faz os atores tão leves, este é o motor damáquina por assim dizer.Todas as implementações de MessageDispatcher são também um ExecutionContext, oque significa que eles podem ser usados para executar código arbitrário.Tenta tirar o melhor proveito possível do recurso Thread, usando adequadamenteThread Pools.Como os atores são isolados, fica fácil para subir novas instâncias em outrasmáquinas e o serviço de endereçamento fica responsável pela entrega dasmensagens.
  29. 29. Haaa, também tem framework web
  30. 30. Real time applications com Playdef index = WebSocket.using[String] { request => // Just consume and ignore the input val in = Iteratee.consume[String]() // Send a single Hello! message and close val out = Enumerator("Hello!") >>> Enumerator.eof (in, out)}Chamada simplesws://localhost:9000/[controller].
  31. 31. Integração com Akkaval myActor = Akka.system.actorOf(Props[MyActor], name = "myactor")Exemplo 1def index = Action { Async { (myActor ? "hello").mapTo[String].asPromise.map { response => Ok(response) } }}Exemplo2def index = Action { Async { Akka.future { longComputation() }.map { result => Ok("Got " + result) } }}Exemplo3Akka.system.scheduler.schedule(0 seconds, 30 minutes, testActor, "tick")Obs: cliente fica esperando, mas servidor pode receber nova conexao
  32. 32. Aspectos comerciais
  33. 33. Monitoramento
  34. 34. Estes são meus motivos, descubra os seus
  35. 35. Estes são meus motivos, descubra os seus
  36. 36. Estes são meus motivos, descubra os seus
  37. 37. Obrigado!CodeSimples.com

×