[1.2] Play'de farkinda olmadigimiz asynchrony sorunu

170 views
Skip to first unread message

Ahmet Alp Balkan

unread,
Mar 20, 2012, 5:11:24 PM3/20/12
to play-fra...@googlegroups.com
Yine uzun bir maille karsinizdayim. Oncelikle kacimiz bu sayfanin ilk 5 paragrafini hatirliyor merak ediyorum. :) Megersem play'de aninda return etmeyen islemleri controller'in icinde yapmaya kalkarsaniz uygulamaniz birakin scale etmeyi, 2-3 kisinin bile ayni anda kullanamadigi bir sistem haline donusuyormus.

Nasil mi oluyor, cok basit bir ornek:

public static void controllerIcindeBirMetod(){
   print 'request geldi'
   sleep 5 sn.
   print 'request bitti'
}

Uygulamanizin bu action'una ayni anda 2 request attiginizda eger ikisinin toplam bitmesi asagi yukari 5 sn surecegini dusunuyorsaniz agir yanilgilardasiniz benim gibi. 10 saniye suruyor, cunku once biri sonra oteki handle ediliyor. (dev modunda boyle en azindan, prod modunda 2 yerine 4 falan yazabilirsiniz, tahmin edersiniz o zaman da 4. sirada gelen request 20 sn sonra cevap alir.)

Ben bu durumun farkinda degildim acikcasi load test yapana kadar. Verdigim sayfada dokumante edilmis demek de yalan olur zira oteki dillerden gelen gelistiriciler icin bu durum vurgulanmamis. Uzucu.

Gelistirdigim sosyal uygulamada cok sayida external servisle synchronous (o an cevap donmem gereken) request icinden iletisim kuruyorum. Cok basit bir ornek, Facebook'uyla baglanan kullanicinin arkadas listesini almam gerekiyor, Facebook API'den bunu synchronous cekiyorum.

Iste bu noktada eger o sayfada belirtilen yeni job yaratip await() metodunu kullanmazsam, 2 kisi ayni anda Facebook arkadaslarini listeleme requestini cagirdiginda kafadan ziyaretcilerin geri kalani siteyi kullanamiyor.

Bu meseleyi ortadan kaldirmak icin bu tarz external requestler veya agir CPU islemleri iceren (diger tabirle returns-immediately olmayan) islerin hepsine yeni job yazmak zorunda kaliyorum. Ayni facebook friend listeleme orneginde, bu isi onceden

List<FacebookFriend> friends = FacebookFriendsProvider.friendsOf(user);

seklinde hallederken simdi:


Job<List<FacebookFriend>> j = new Job<List<FacebookFriend>>(){
    private User user;

    public void setUser(User u){ user = u;}
    
    @Override
    public List<FacebookFriend> doJobWithResult() throws Exception {
        return FacebookFriendsProvider.friendsOf(user);
    }
}.setUser(myUser);
List<FacebookFriend> result = await(j.now());

gibi "igrenc" bir yontemle yapmak zorunda kaliyorum. Kaldi ki bu sekilde 15 civari external synchronous requestimiz var, hepsini cevirmek zorunda kaldik.

Simdi merak ediyorsunuz, nesi sacma bunun diye, bence su sebeplerden:

1) Job execution'lar safe degil, calisacaklarinin garantisi yok.

2) Job'lar arkaplanda calistiklari icin firlattiklari exceptionlar log olarak gorunuyor sadece, size de await'in sonucu null donuyor, icerde ne olup bittigini ogrenemiyorsunuz.

3) Hele bizim gibi validation icin exception-driven bir stratejiniz varsa, ornegin bu metodlariniz ResourceNotFoundException, InsufficientPrivilegesException gibi durumu anlatan exceptionlar atiyorsa cagirdiginiz servisin (yani bu ornekte facebook'tan friend'leri cekmenin) ne tip bir hata dondurdugunu asla bilemeyeceksiniz.

4) Son igrenclik sebebi bos yere tek satirlik kodu 15 satir yapivermesi.

Henuz (1) nolu maddeden zarar gormedim ama kalan kisim benim icin cok onemliydi. Peki ben ne mi yaptim?:

  • Job'un return type'ini Object yaptim.
  • Bu sekilde istersem List<FacebookFriend> istersem Exception dondurebiliyorum.
    • Yani servisim exception firlatirsa ben de onu yukari throw etmek yerine job result gibi donduruyorum.
  • Controller action'umda instanceof yardimiyla sonuc exception'sa ilgili islemi yapiyorum (orn, kullaniciya sifreniz yanlis falan diyorum)
    • Degilse, yani sonuc List<FacebookFriend> ise sonucu kullaniyorum.
  • Sonuc olarak daha igrenc, yepisyeni bir dirty hack ortaya cikarmis oluyorum.
Simdi suc kimde ve niye? Hepimizin external servislerle, Solr-Lucene vb modullerle, agir DB islemleriyle, upload edilen dosyayi save eden, clouda upload eden librarylerle etkilesen uygulamalar yazdigi ve en onemlisi birlik ve beraberlige her zamankinden daha cok ihtiyac duydugumuz su zamanlarda sizi bu konuya duyarli olmaya davet ediyorum. 

Saygilar.

--
Ahmet Alp Balkan

deniz silahcılar

unread,
Mar 20, 2012, 5:47:29 PM3/20/12
to play-fra...@googlegroups.com
Oncelikle playle dokumantasyonunu okumaktan ote bir iliskim olmadigi, yani tamamen tahminsel konustugumu belirterek konuya gireyim :)

2012/3/20 Ahmet Alp Balkan <ahmetal...@gmail.com>


Uygulamanizin bu action'una ayni anda 2 request attiginizda eger ikisinin toplam bitmesi asagi yukari 5 sn surecegini dusunuyorsaniz agir yanilgilardasiniz benim gibi. 10 saniye suruyor, cunku once biri sonra oteki handle ediliyor. (dev modunda boyle en azindan, prod modunda 2 yerine 4 falan yazabilirsiniz, tahmin edersiniz o zaman da 4. sirada gelen request 20 sn sonra cevap alir.)


Dev modunda debugging kolay olsun diye pool size 1 geliyor. O yuzdende istekleri bekletmesi normal. Prod' da ise islemci sayisi +1 deniyor. Uygulama cloud uzerinde kosacaksa bu sayi kabul edilebilir seviyelere cikabilir diye dusunuyorum. Ayrica kendi sunucumuzda calistirmak istersek de play.pool degerini yuke gore zamanla arttirabiliriz. Ornegin Tomcatte default thread sayisi 200 olarak geliyor. 
 

Ahmet Alp Balkan

unread,
Mar 20, 2012, 6:47:31 PM3/20/12
to play-fra...@googlegroups.com
Peki core+1 kuralinin baglayiciligi var mi, ben kafama gore eh denecek makinada pool'da 20-30 thread bulundursam ciddi bir sorun olur mu? Tomcat genelde saglam makinalarda mi kosturuluyorki default 200? Bu konuda biseylere yonlendirebilirseniz cok sevinirim.

deniz silahcılar

unread,
Mar 20, 2012, 8:10:35 PM3/20/12
to play-fra...@googlegroups.com
Aslinda thread sayisinin arttirilmasi sistemin nasil kullanilacagina gore degisebilir. Thread sayisinin artmasi memory kullaniminin artmasi demek o da context switch suresinin artmasina neden olur.  Ayni anda 100 istege cevap vermek onemliyse thread sayisi 100 olabilir ama onemli olan hizli yanit vermek ise thread sayisini 10' a dusurup gelen 10 istegin hizlica cevap vermeyi secebilirsiniz. 

Bence 20-30 threadin sorun olmamasi gerekir. Ama yine de test edip gormek en sagliklisi. Apache ab testlerde isinizi kolaylastirabilir. 

Bu konuda weblogic dokumantasyonu fena durmuyor. 

http://docs.oracle.com/cd/E13222_01/wls/docs81/perform/WLSTuning.html#1140013

Ayrica 2.0 da bu parametre kaldirilmis. Default degerin kac oldugunu ve nasil degistirilebildigini de bulamadim. 


2012/3/21 Ahmet Alp Balkan <ahmetal...@gmail.com>

Huzeyfe Borazan

unread,
Mar 21, 2012, 4:52:32 AM3/21/12
to play-fra...@googlegroups.com
Merhabalar,

Play Framework ile henuz yeni yeni arkadas oldugumuz icin konu hakkinda derin tahliller yapmaktan biraz uzaktayim. Fakat merak ettigim bir sey oldu. Bu tur async. ve agir islemler icin messaging queue tarzi mesela RabbitMQ (Play icin super-easy modulleri de var) kullanmayi dusundun mu? Bunun job'a gore artisi eksisi neler bir fikrin var mi?

Iyi Calismalar..
--
Huzeyfe BORAZAN

Ahmet Alp Balkan

unread,
Mar 21, 2012, 4:56:58 AM3/21/12
to play-fra...@googlegroups.com
Huzeyfe bey merhabalar,

Halihazirda async task'lar icin RabbitMQ kullaniyoruz, fakat play.Job'larinin guzel yani kendileri play.f.Future<?> adinda override ettikleri java.concurrency.Future class'lari ve Promise<?> class'lari var await metoduyla uyumlu calisan. 

Yani sanirim RabbitMQ ile Future veya Promise yaratip sonucunu alabilmek icin epey kod yazariz gibi duruyor. Su an icin play-rabbitmq modulunu kullaniyoruz ve sonucunu almamak uzere sadece task publish edip retry mekanizmansindan faydalaniyoruz. Cunku dedigim gibi baslikta asynchrony yazsam da aslinda cevaplara sync olarak ihtiyacim var ve play Job'larin sonuclarini bekleyene kadar thread'i suspend edebilen await metoduyla uyumlu calisiyor.

Sizin bildiginiz sync response alabilmek icin rabbitmq kullanma yontemi var mi? Varsa da Job'dan daha fazla overhead oluyor gibime geldi benim.

Fehmi Can Sağlam

unread,
Mar 21, 2012, 5:19:05 AM3/21/12
to play-fra...@googlegroups.com

Selam,

Konuyla ilgili daha önce parça parça yazmıştım aslında. Işin özünde bir trade-off var ve ilk boş vakitte uzun bir blog yazmak gerekiyor gibi. Neden non-blocking IO, neden Tomcat "eski teknoloji", neden Java ile ancak bu kadar, vs...

Ahmet, kodu biraz daha toparlamak için anonymous inner class yerine ayrı Job sınıfları yazabilirsin sanıyorum. Ama bunun dışında yapacak pek bir şey yok gibi ne yazık ki.

21 Mar 2012 10:57 tarihinde "Ahmet Alp Balkan" <ahmetal...@gmail.com> yazdı:

Huzeyfe Borazan

unread,
Mar 21, 2012, 5:26:56 AM3/21/12
to play-fra...@googlegroups.com
Merhaba Alp,

Bu arada belirteyim bu grupta samimi bir ortam gordugum icin normalde tanimadigim insanlara siz diye hitap ederken ve genel "bey" derken burada kullanmadim ;)

Konuya donecek olursak daha uykum tam acilmadigi ve kahvemi henuz icmedigim icin baslikta async. yazmana ragmen cevaplari sync. alman gerektigini simdi idrak edebildim :)) Bu durumda sanirim senin cozumunden daha boyle super bi cozum aklimda yok acikcasi ama belki kodu biraz daha kullanisli hale getirebilirsin. Job siniflari vs. gibi..

Sana katiliyorum eger sync. alacaksan ve bunu rabbitmq ile yapsan dahi bi overhead olacagi hissi bende de uyaniyor..

Selamlar.. 
--
Huzeyfe BORAZAN

Erdem Agaoglu

unread,
Mar 21, 2012, 7:08:36 AM3/21/12
to play-fra...@googlegroups.com
Selamlar,

Fehmi Hocam'in blog yazisini beklerken bir seyler de ben atiyim ortaya. Ya da aralara...

2012/3/20 Ahmet Alp Balkan <ahmetal...@gmail.com>
Yine uzun bir maille karsinizdayim. Oncelikle kacimiz bu sayfanin ilk 5 paragrafini hatirliyor merak ediyorum. :) Megersem play'de aninda return etmeyen islemleri controller'in icinde yapmaya kalkarsaniz uygulamaniz birakin scale etmeyi, 2-3 kisinin bile ayni anda kullanamadigi bir sistem haline donusuyormus.

Nasil mi oluyor, cok basit bir ornek:

public static void controllerIcindeBirMetod(){
   print 'request geldi'
   sleep 5 sn.
   print 'request bitti'
}

Uygulamanizin bu action'una ayni anda 2 request attiginizda eger ikisinin toplam bitmesi asagi yukari 5 sn surecegini dusunuyorsaniz agir yanilgilardasiniz benim gibi. 10 saniye suruyor, cunku once biri sonra oteki handle ediliyor. (dev modunda boyle en azindan, prod modunda 2 yerine 4 falan yazabilirsiniz, tahmin edersiniz o zaman da 4. sirada gelen request 20 sn sonra cevap alir.)

Sayilarda bazi hatalar var gibi ama onemli degil, kavramlar harfiyen dogru.
 

Ben bu durumun farkinda degildim acikcasi load test yapana kadar. Verdigim sayfada dokumante edilmis demek de yalan olur zira oteki dillerden gelen gelistiriciler icin bu durum vurgulanmamis. Uzucu.

Evet dokumantasyonda vurgulanmamis ama bunun sebebi durumun play ozelinde bir problem olmamasi. Bunlar genel concurrency kavramlari, bazi isimlerde degisiklikler olabilse de aslinda frameworkler ve hatta diller ustu kavramlar. (Java da ThreadPool ve Executor, C++ Boost'ta threadpool, python da multiprocessing.pool.ThreadPool, ruby icin cesitli snippetlar...)
 

Gelistirdigim sosyal uygulamada cok sayida external servisle synchronous (o an cevap donmem gereken) request icinden iletisim kuruyorum. Cok basit bir ornek, Facebook'uyla baglanan kullanicinin arkadas listesini almam gerekiyor, Facebook API'den bunu synchronous cekiyorum.

Facebook API ya da bir cok web servis sync calisiyor olabilir. Ama bu client'larin da sync calismasi gerektigi anlamina gelmez. Comet olmayan duz bir ajax islem dusunun, aslinda protokol bakimindan o metot sync'tir (HTTP Request ve Response). Fakat javascript client'i o islemi async haline getirir.
 

Iste bu noktada eger o sayfada belirtilen yeni job yaratip await() metodunu kullanmazsam, 2 kisi ayni anda Facebook arkadaslarini listeleme requestini cagirdiginda kafadan ziyaretcilerin geri kalani siteyi kullanamiyor.

Bu meseleyi ortadan kaldirmak icin bu tarz external requestler veya agir CPU islemleri iceren (diger tabirle returns-immediately olmayan) islerin hepsine yeni job yazmak zorunda kaliyorum. Ayni facebook friend listeleme orneginde, bu isi onceden

Boyle bir zorunluluk yok. devami asagida...
 

List<FacebookFriend> friends = FacebookFriendsProvider.friendsOf(user);

seklinde hallederken simdi:


Job<List<FacebookFriend>> j = new Job<List<FacebookFriend>>(){
    private User user;

    public void setUser(User u){ user = u;}
    
    @Override
    public List<FacebookFriend> doJobWithResult() throws Exception {
        return FacebookFriendsProvider.friendsOf(user);
    }
}.setUser(myUser);
List<FacebookFriend> result = await(j.now());

gibi "igrenc" bir yontemle yapmak zorunda kaliyorum. Kaldi ki bu sekilde 15 civari external synchronous requestimiz var, hepsini cevirmek zorunda kaldik.

Problem (tabi bu bir problem olarak goruluyorsa) mimari acidan API client'dan (FacebookFriendsProvider) kaynakli. Eger bunu disardan bulduysaniz async bir facebook client bulmanizda fayda var. Kendiniz yazdiysaniz metotlari Future dondurecek sekilde degistirmelisiniz. 

Durum aslinda play'in fixedthreadpool kullanmasiyla ayni mantik, yukaridaki ornekte her bir request icin bir job acip arkaplana atarsaniz 1000 kisi ayni anda arkadas listesini istedigi durumda play 1000 tane job ile facebook'a 1000 tane request gonderecektir. Bu sunucuda bir problem yaratmasa bile facebook tarafindan bir atak gibi algilanabilir sunucuyu engellemesine sebep olabilir. (goo.gl icin yaptim ordan biliyorum)

Diger taraftan kendi threadpool'unu kullanan daha akilli bir client bu gibi istekleri kontrol altinda tutabilir. Ayrica Future dogrudan await'e gecirilebiliyordu diye hatirliyorum.
 

Simdi merak ediyorsunuz, nesi sacma bunun diye, bence su sebeplerden:

1) Job execution'lar safe degil, calisacaklarinin garantisi yok.

Facebook'un cevap vereceginin de garantisi yok. Kabaca concurrent uygulamalarda hic bir seyin garantisi yok. Bu karsilasilan ilk zorluk...
 

2) Job'lar arkaplanda calistiklari icin firlattiklari exceptionlar log olarak gorunuyor sadece, size de await'in sonucu null donuyor, icerde ne olup bittigini ogrenemiyorsunuz.

Bu zorluklardan bir digeri.
 

3) Hele bizim gibi validation icin exception-driven bir stratejiniz varsa, ornegin bu metodlariniz ResourceNotFoundException, InsufficientPrivilegesException gibi durumu anlatan exceptionlar atiyorsa cagirdiginiz servisin (yani bu ornekte facebook'tan friend'leri cekmenin) ne tip bir hata dondurdugunu asla bilemeyeceksiniz.

Normal durumda dogrudur. Bu da baska bir zorluk. Asagida bununla ilgili bir cozum yapmissiniz, diger bir oneriyi oraya ekleyecegim.
 

4) Son igrenclik sebebi bos yere tek satirlik kodu 15 satir yapivermesi.

Henuz (1) nolu maddeden zarar gormedim ama kalan kisim benim icin cok onemliydi. Peki ben ne mi yaptim?:

  • Job'un return type'ini Object yaptim.
  • Bu sekilde istersem List<FacebookFriend> istersem Exception dondurebiliyorum.
    • Yani servisim exception firlatirsa ben de onu yukari throw etmek yerine job result gibi donduruyorum.
  • Controller action'umda instanceof yardimiyla sonuc exception'sa ilgili islemi yapiyorum (orn, kullaniciya sifreniz yanlis falan diyorum)
    • Degilse, yani sonuc List<FacebookFriend> ise sonucu kullaniyorum.
  • Sonuc olarak daha igrenc, yepisyeni bir dirty hack ortaya cikarmis oluyorum.
Burada kullanilabilecek bir diger yontem Either gibi bir yapi kullanmak. yani metot Either<Throwable, List<FacebookFriend>> gibi bir sey donecek (hatta Future<Either<Throwable, List<FacebookFriend>>>). Bu seyin icinde atiyorum isLeft(), isRight(), getLeft(), getRight() gibi metotlar olacak. Hatta simdi baktim play in icinde varmis play.libs.F.Either seklinde bir ornek. Boylece typesafe olunacak.
 
Simdi suc kimde ve niye? Hepimizin external servislerle, Solr-Lucene vb modullerle, agir DB islemleriyle, upload edilen dosyayi save eden, clouda upload eden librarylerle etkilesen uygulamalar yazdigi ve en onemlisi birlik ve beraberlige her zamankinden daha cok ihtiyac duydugumuz su zamanlarda sizi bu konuya duyarli olmaya davet ediyorum. 

Buyrun burdan yakin diyorum. Butun bunlardaki asil problem tum bu islerin zor olmasi. Duz hepimizin alistigi akis diyagramlarindan vs'den farkli calisiyor olmasi. Bu yuzden play zaten typesafe'e ve scala'ya ve akka'ya yaklasti (heralde). Zira akka kullanarak, scala kullanarak, bazi fonksiyonel programlama araclarini kullanarak bu isler biraz daha kolaylasiyor. Ha beraberinde baska zorluklar getirmiyor mu, o ayri bir konu.
 

Saygilar.

--
Ahmet Alp Balkan

Herkese kolay gele


--
erdem agaoglu

Fehmi Can Sağlam

unread,
Mar 21, 2012, 7:26:33 AM3/21/12
to play-fra...@googlegroups.com
Erdem Hocam, yazıya gerek bırakmamışsın:)
Daha önce Cache Manager için yaptığımız gibi gistler hazırlayabilirsek güzel olur aslında.

21 Mart 2012 Çarşamba 13:08:36 UTC+2 tarihinde Erdem Agaoglu yazdı:

Ahmet Alp Balkan

unread,
Mar 21, 2012, 8:01:18 AM3/21/12
to play-fra...@googlegroups.com
Hocam über adamsin gercekten cok tesekkurler. Aydinlandim. Pair gibi bisey kullanmak aklima nedense gelmedigi gibi play'in icinde Either oldugunu da bilmiyordum. (hatta E2, E3, E4, E5 bile varmis, bilginize).

Yine cok guzel bir muhabbet döndü, sagolun :) Icten tesekkurlerimi sunarim.

Erdem Agaoglu

unread,
Mar 21, 2012, 11:48:33 AM3/21/12
to play-fra...@googlegroups.com
Ne demek efenim, rica ederiz. Klavyemiz yettigi kadar muhabbet ederiz daha, serin bir ortam kuruyoruz netekim :)

2012/3/21 Ahmet Alp Balkan <ahmetal...@gmail.com>
Hocam über adamsin gercekten cok tesekkurler. Aydinlandim. Pair gibi bisey kullanmak aklima nedense gelmedigi gibi play'in icinde Either oldugunu da bilmiyordum. (hatta E2, E3, E4, E5 bile varmis, bilginize).



--
erdem agaoglu

Volkan YAZICI

unread,
Mar 25, 2012, 5:48:10 AM3/25/12
to play-fra...@googlegroups.com
OSGi ve JGroups ile boğuşmaktan ancak nefes alabiliyorum, yorumlarım aşağıda.


On Wednesday, March 21, 2012 1:08:36 PM UTC+2, Erdem Agaoglu wrote:
Problem (tabi bu bir problem olarak goruluyorsa) mimari acidan API client'dan (​FacebookFriendsProvider) ​kaynakli. Eger bunu disardan bulduysaniz async bir facebook client bulmanizda fayda var. Kendiniz yazdiysaniz metotlari Future dondurecek sekilde degistirmelisiniz. 

Durum aslinda play'in fixedthreadpool kullanmasiyla ayni mantik, yukaridaki ornekte her bir request icin bir job acip arkaplana atarsaniz 1000 kisi ayni anda arkadas listesini istedigi durumda play 1000 tane job ile facebook'a 1000 tane request gonderecektir. Bu sunucuda bir problem yaratmasa bile facebook tarafindan bir atak gibi algilanabilir sunucuyu engellemesine sebep olabilir. (goo.gl icin yaptim ordan biliyorum)

Diger taraftan kendi threadpool'unu kullanan daha akilli bir client bu gibi istekleri kontrol altinda tutabilir. Ayrica Future dogrudan await'e gecirilebiliyordu diye hatirliyorum.

Aslında su yüzüne çıkmış bu (so-called) defficiency, insanları bir çok noktada single process/thread ve async server mimarilerine itmeye başladı. Bunun en net örneğini bence NodeJS tarafından yaşanan hype'ta görüyoruz. Aynı şeyi ben de bazen düşünmüyor değilim: JVM aslında single process geliştirilse de thread'ler eskisi gibi green/lightweight olsa; ve multicore olayını da ben kendi programımı birden fazla spawn ettiğim JVM'ler üzerinde halletsem. (Bkz. Reddit) Fakat bunun için V8'in Javascript'e yaptığına benzer olarak, JVM'in Java'ya sunduğu tüm fonksiyon ailesinin async olması lazım ki tüm bu emeğin bir anlamı olsun.

Durumu biraz da aydınlığa kavuşturmak adına, Ahmet, aynı kodu NodeJS üzerinde yazmış olsaydın şöyle olacaktı:

function index(httpReq, user) {
  FB.friendsOf(user, function() {
    // Rest of your index() logic goes here.
    httpReq.write(...);
  });
}

Yani nerede async metodlar, orada callback çorbası. Bu yüzden Play'in await()'ine biraz da şükretmek lazım.

Bu arada şimdi düşündüm de NodeJS'e başka ne örnek verebiliriz diye, aklıma Gambit Scheme geldi. Hatta o cepheden Future tipinde yaklaşımlar ile benzer bir başarı hikayesi: Termite Scheme.
Burada kullanilabilecek bir diger yontem Either gibi bir yapi kullanmak. yani metot Either<Throwable, List<FacebookFriend>> gibi bir sey donecek (hatta Future<Either<Throwable, List<FacebookFriend>>>). Bu seyin icinde atiyorum isLeft(), isRight(), getLeft(), getRight() gibi metotlar olacak. Hatta simdi baktim play in icinde varmis play.libs.F.Either seklinde bir ornek. Boylece typesafe olunacak.

Haskell'ın Maybe'si, Scala'nın Option'ı, Play'in Either'ı, vs. Yani Common Lisp'in multiple-value-return'ünü özleyen yok mu şimdi?

Fehmi Can SAĞLAM

unread,
Mar 25, 2012, 9:24:28 AM3/25/12
to play-fra...@googlegroups.com
Node.js'i production ortamında kullanıyor musunuz?

On Sun Mar 25 12:48:10 2012, Volkan YAZICI wrote:
> OSGi ve JGroups ile boğuşmaktan ancak nefes alabiliyorum, yorumlarım
> aşağıda.
>
> On Wednesday, March 21, 2012 1:08:36 PM UTC+2, Erdem Agaoglu wrote:
>
> Problem (tabi bu bir problem olarak goruluyorsa) mimari acidan API
> client'dan (​FacebookFriendsProvider) ​kaynakli. Eger bunu
> disardan bulduysaniz async bir facebook client bulmanizda fayda
> var. Kendiniz yazdiysaniz metotlari Future dondurecek sekilde
> degistirmelisiniz.
>
> Durum aslinda play'in fixedthreadpool kullanmasiyla ayni mantik,
> yukaridaki ornekte her bir request icin bir job acip arkaplana
> atarsaniz 1000 kisi ayni anda arkadas listesini istedigi durumda
> play 1000 tane job ile facebook'a 1000 tane request gonderecektir.
> Bu sunucuda bir problem yaratmasa bile facebook tarafindan bir
> atak gibi algilanabilir sunucuyu engellemesine sebep olabilir.

> (goo.gl <http://goo.gl> icin yaptim ordan biliyorum)


>
> Diger taraftan kendi threadpool'unu kullanan daha akilli bir
> client bu gibi istekleri kontrol altinda tutabilir. Ayrica Future
> dogrudan await'e gecirilebiliyordu diye hatirliyorum.
>
>
> Aslında su yüzüne çıkmış bu (so-called) defficiency, insanları bir çok
> noktada single process/thread ve async server mimarilerine itmeye
> başladı. Bunun en net örneğini bence NodeJS tarafından yaşanan hype'ta
> görüyoruz. Aynı şeyi ben de bazen düşünmüyor değilim: JVM aslında
> single process geliştirilse de thread'ler eskisi gibi
> green/lightweight olsa; ve multicore olayını da ben kendi programımı
> birden fazla spawn ettiğim JVM'ler üzerinde halletsem. (Bkz. Reddit)
> Fakat bunun için V8'in Javascript'e yaptığına benzer olarak, JVM'in
> Java'ya sunduğu tüm fonksiyon ailesinin async olması lazım ki tüm bu
> emeğin bir anlamı olsun.
>
> Durumu biraz da aydınlığa kavuşturmak adına, Ahmet, aynı kodu NodeJS
> üzerinde yazmış olsaydın şöyle olacaktı:
>
> function index(httpReq, user) {
> FB.friendsOf(user, function() {
> // Rest of your index() logic goes here.
> httpReq.write(...);
> });
> }
>
> Yani nerede async metodlar, orada callback çorbası. Bu yüzden Play'in
> await()'ine biraz da şükretmek lazım.
>
> Bu arada şimdi düşündüm de NodeJS'e başka ne örnek verebiliriz diye,

> aklıma Gambit Scheme <http://www.iro.umontreal.ca/%7Egambit/> geldi.

> Hatta o cepheden Future tipinde yaklaşımlar ile benzer bir başarı

> hikayesi: Termite Scheme <http://code.google.com/p/termite/>.

Volkan YAZICI

unread,
Mar 25, 2012, 3:11:01 PM3/25/12
to play-fra...@googlegroups.com
Henüz öyle bir şansım olmadı. Aslında deneyimim de, şu ana kadar kullandığım NodeJS tool'ları (RailwayJS, vs.) da öyle bir şeye çok elverişli değil.
Reply all
Reply to author
Forward
0 new messages