3 puan yazan GN⁺ 2023-12-08 | 1 yorum | WhatsApp'ta paylaş
  • FLAME, mevcut uygulama kodunun bir bölümünü bir fonksiyonla sarıp geçici bir uygulama kopyasında çalıştırarak, kodu ayrı bir runtime’a taşımadan ince taneli elastik ölçekleme hedefler
  • Mevcut FaaS yaklaşımı, video küçük resmi oluşturma gibi işlerde bile HTTP, S3, SQS, API Gateway, encoder/decoder ve iş akışı orkestrasyonunun arttığı bir yapı oluşturabilir
  • Elixir’in flame library’si FLAME.call ile fonksiyon çalıştırmayı uzak runner’a devreder; Fly.io’nun FLAME.FlyBackend’i aynı Docker imajıyla yeni bir Fly Machine başlatıp yaklaşık 3 saniye içinde parent node’a bağlar
  • Geliştirme ve testte LocalBackend ile aynı runtime’da çalıştırılır; production’da min, max, max_concurrency, idle_shutdown_after ile scale-to-zero ve kısa süreli hot durumda kalma ayarlanır
  • FLAME, iş kuyruğunu ortadan kaldırmaktan çok dayanıklılık garantisi ile elastik çalıştırmayı ayırır; kuyruk dispatch·commit·retry işlerini üstlenirken CPU yoğun işler FLAME çağrısı içinde işlenir

FLAME deseninin hedeflediği sorun

  • Elastik otomatik ölçekleme, sunucu yönetimi yükünü azaltmayı ve kullanıma dayalı maliyetleri vaat eder; ancak FaaS kullanıldığında ayrı kuyruklar, depolama, glue code ve geliştirme·test·CI karmaşıklığı da artabilir
  • FLAME, Fleeting Lambda Application for Modular Execution ifadesinin kısaltmasıdır; tüm uygulamayı lambda gibi ele alıp yalnızca bazı modül işlerini kısa süreli ayağa kalkan altyapıda çalıştırma yaklaşımıdır
  • Hedef üç başlıkta özetlenir
    • fly deploy, git push heroku, kubectl gibi mevcut dağıtım akışlarıyla sunucu yönetimini azaltmak
    • Uygulama kodunun yalnızca belirli bölümlerini isteğe bağlı, ince taneli ölçeklemek
    • Uygulamayı yeniden yazmamak veya kodun bir kısmını özel bir runtime’a taşımamak

Mevcut fonksiyonları FLAME.call ile taşımak

  • Örnek, bir Elixir uygulamasında yüklenen videoyu ffmpeg ile küçük resimlere dönüştüren generate_thumbnails fonksiyonudur
  • Mevcut fonksiyon geçici bir dizin oluşturur, ffmpeg çalıştırır, ardından üretilen küçük resimleri dayanıklı depolamaya kaydeder ve URL’leri DB’ye Repo.insert_all ile yazar
  • CPU yoğun video transcoding production’da tüm servisi durdurabileceği için, kodun tamamını FaaS’e veya mikroservise taşımadan fonksiyon gövdesi FLAME.call(MyApp.FFMpegRunner, fn -> ... end) ile sarılır
  • FLAME.call, runner pool adı ve bir fonksiyon alır; tüm uygulamanın yeni bir kopyasını bulur veya başlatır, sonra yalnızca o fonksiyonu çalıştırır
    • Fonksiyonun closure içinde yakaladığı %Video{} struct’ı ve interval gibi değişkenler otomatik olarak aktarılır
    • FLAME runner, başlatıldıktan sonra parent node’a bağlanır, çalıştırılacak fonksiyonu alır ve sonucu çağırana döndürür
    • Ayara bağlı olarak runner ek işler beklerken idle durumda kapanır veya hemen sonlandırılır
  • DB bağlantısı dahil tüm uygulama çalıştığı için, özgün koddaki gibi Repo.insert_all aynen kullanılabilir

FaaS karmaşıklığı ve FLAME’in farkı

  • FaaS, problemi çözmek için bileşenler sunar; FLAME ise ayrı iletişim katmanını azaltan bir yaklaşıma daha yakındır
  • Video küçük resmi örneğinde basit bir AWS Lambda Function URL ile başlansa bile kısa sürede karmaşıklık ortaya çıkar
    • Küçük resimleri HTTP üzerinden uygulamaya geri stream etmek için iki tarafta da özel encoder ve decoder yazmak gerekir
    • Video transcoding veya upload 15 dakikayı aşarsa Lambda’nın sert timeout sınırı nedeniyle videoyu parçalara bölmek ve daha fazla Lambda kullanmak gerekir
    • İş akışı orkestrasyonu ve SQS, S3 gibi ek servisler gerekli hale gelir
  • FaaS tabanlı uygulamalar genelde şu maliyet noktalarını oluşturur
    • HTTP endpoint, S3, API Gateway ile Lambda tetikleme
    • Video transcoding için özel Lambda yazma
    • Küçük resim sonucunu SQS’e kaydetme
    • Uygulama tarafında SQS consumer yazma
    • DB’ye kaydetme ve başka instance’lara bağlı aktif abonelere event’leri geri iletmenin yolunu kurma
  • FLAME, uygulama içi kodu ve mevcut DB, PubSub, platform özelliklerini aynen kullandırdığı için ayrı servisleri ve sonuçları geri almak için gereken depolamayı azaltabilir

Fly.io backend’i ve yerel çalıştırma

  • Elixir flame library, FLAME deseninin bir implementasyonudur ve varsayılan olarak LocalBackend ile FlyBackend sağlar
  • FLAME.FlyBackend, Fly.io altyapısında yeni bir Machine üzerinde uygulama kopyasını başlatır ve yaklaşık 3 saniye içinde parent node’a bağlanıp iş alabilir
  • Fly.io uygulamaları paketlenmiş Docker imajları olarak çalıştırdığı için, Fly API’den mevcut uygulamayla aynı imaja sahip yeni bir Machine başlatması istenir
  • Fly.io altyapısında FLAME runner’ı parent ile aynı region’da başlatmak mümkün olduğundan parent ile runner arasındaki gecikme azaltılabilir
  • FLAME.FlyBackend, dokümantasyon dahil 200 LOC’den az ve library bağımlılığı yalnızca HTTP client req’dir
  • Geliştirme ve testte LocalBackend ile kod, dizüstü bilgisayarın veya CI sunucusunun mevcut runtime’ında çalıştırılır

Dosya aktarımı ve geliştirme·testin sadeleşmesi

  • FLAME, uygulama dışında kod yazmadan iş mantığını, DB ayarlarını, PubSub’ı ve platform özelliklerini yeniden kullanabilir
  • Elixir’de Erlang VM’in dağıtık özellikleri sayesinde parent node’daki dosya stream’i uzak FLAME uygulamasına gönderilebilir
    • Parent node’da video yolunun dosya stream’i açılır
    • FLAME child içinde geçici dosya stream’i açılır ve parent stream’i kopyalanır
    • Sonrasında ffmpeg, küçük resimleri üretmek için uzak runner’daki geçici dosyayı input olarak kullanır
  • Bu yöntemde dosyayı FLAME sunucusuna aktarmak için ayrıca S3 veya HTTP arayüzü kurmak gerekmez
  • Ayrı servis dağıtımı, endpoint yönetimi, S3/SQS üzerinden sonuç geri alma, geliştirme·test·CI bağımlılık yapılandırması azalır

Elixir dışında FLAME

  • Elixir süreç supervision’ı ve dağıtık mesajlaşma sunduğu için FLAME modeline iyi uyar; ancak makul concurrency primitive’lerine sahip diller de bu deseni kullanabilir
  • JavaScript proof of concept örneği, Fly Machine’de uygulama fonksiyonunu başka bir machine’de çalıştırma biçimindedir: fly-run-this-function-on-another-machine
  • JavaScript tabanlı FLAME çağrısının genel akışı, modül çalıştırma bölümünü yeni bir dosyaya taşıyıp runner pool’da çalıştırma şeklindedir
  • Argümanlar JSON serialize edilebiliyorsa tüm akış Elixir örneğine benzer biçimde, uygulama kodunun kısa süreli ayağa kalkan instance’ta çalışmasıyla ilerler
  • Tam bir FLAME library’si şunları ele almalıdır
    • Elastik pool scale-up ve scale-down mantığı
    • Hot startup ve cold startup dikkate alınarak pool yönetimi
    • Orphaned resource’ları önlemek için uzak runner izleme
    • Dağıtımları güncel tutma yöntemi

Arka plan iş kuyruklarıyla ilişkisi

  • FLAME arka plan işleyicileri içinde de çalışır, ancak iş kuyruklarıyla rolünün örtüştüğü noktalar vardır
  • İş kuyrukları genelde dayanıklılık garantisi gerektiğinde kullanılır; kuyruk daha fazla işi yük değişimine göre işleyecek şekilde ayarlanabilir
  • Dayanıklı işler ile elastik çalıştırma ayrı konulardır
    • Kuyruk yalnızca offload çalıştırma amacıyla kullanılırsa işe veri koymak, sonucu çağırana veya kullanıcı cihazına geri döndürmek için glue code gerekir
    • Video upload’dan sonra küçük resim üretiminin başarılı olmasını garanti etmek gerekiyorsa kuyruk dispatch, commit, retry mekanizmalarını üstlenebilir
    • Asıl transcoding, işin içindeki FLAME çağrısıyla çalıştırılarak dayanıklılık ile ölçekli çalıştırma ayrılabilir
  • Kaydetmeden önce video önizlemesi veya kullanıcının uygulamadan ayrılmış olduğu ML modeli çalıştırma gibi dayanıklılık gerektirmeyen işler, işi dayanıklı depolamaya yazan yapıyla uyuşmayabilir

Elastik ölçekleme için runner pool

  • Elixir FLAME implementasyonu, runner’ların elastik pool’unu tanımlayarak scale-to-zero ve concurrency limitlerini birlikte destekler
  • Örnek ayar, FLAME.Pool’u uygulamanın start/2 fonksiyonuna ekler
    • min: 0 ile scale-to-zero’ya izin verir
    • max: 10 ile en fazla 10 runner başlatır
    • max_concurrency: 5 ile runner başına 5 ffmpeg işini destekler
    • idle_shutdown_after: 30_000 ile 30 saniye çağrı işi olmazsa idle down yapar
  • FLAME parent’ın varlığına göre Phoenix web sunucusu koşullu olarak başlatılır
    • Web trafiği işlemeyen FLAME runner’da web sunucusunu başlatmak gerekmez
    • DB gibi MyApp.Repo ise FLAME runner içinde kullanılacağı için aynen bırakılır
  • min: 1 verilirse uygulama başlangıcından itibaren en az bir ffmpeg runner hot durumda tutulabilir

Durumlu süreç yerleşimi

  • Elixir uygulamasının stateful bölümleri, mesaj mailbox’ına sahip hafif süreç primitive’leri etrafında kurulur
  • FLAME.call ve FLAME.cast görece stateless koda uygundur; FLAME.place_child ise mevcut process spec’in yerel yerine FLAME runner’da başlatılmasını sağlar
  • FLAME.place_child, Task.Supervisor.start_child, DynamicSupervisor.start_child gibi arayüzlerin kullanıldığı yerlerde kullanılabilir
  • LiveView upload sırasında küçük resim üretme örneğinde upload chunk’ları ThumbnailGenerator sürecine iletilir ve bu süreç ffmpeg ile iletişim kurar
    • ffmpeg stdout içinde PNG delimiter bulunduğunda LiveView sürecine image mesajı gönderir
    • LiveView, handle_info içinde mesajı alıp UI’a yeni resmi ekler
  • Mevcut DynamicSupervisor.start_child(@sup, spec) çağrısı FLAME.place_child(Thumbs.FFMpegRunner, spec) ile değiştirilirse ThumbnailGenerator süreci FLAME runner’da çalışır
  • Süreçler konumdan bağımsız olarak mesaj alışverişi yapabildiği için, upload bittiğinde veya tarayıcı sekmesi kapandığında süreç sona ererse FLAME sunucusu sonlanmayı algılar ve başka iş yoksa idle down yapar

Uzak izleme ve hata işleme

  • Kısa süreli ayağa kalkan altyapıda orphaned resource’ları önlemek için failsafe gerekir
  • Parent runner’ı ayağa kaldırdığında, runner iş yokken kendi kendine idle down yapmalı; parent node ile artık iletişim kuramıyorsa failsafe shutdown uygulamalıdır
  • Yeni dağıtımda parent değiştirildiğinde, cluster’da aynı kodun çalıştığını garanti etmek için runner da kapatılmalıdır
  • Runner iş sonucunu bekleyen aktif çağıranlar, runner’ın herhangi bir nedenle kapanması ihtimalini hesaba katmalıdır
  • Erlang VM’in sunduğu primitive’ler bu implementasyonu basitleştirir
    • Yerel·uzak süreç izleme ve supervision
    • Node’ların ayağa kalkıp kapanmasını algılayan node monitoring
    • Uygulama başlatma·kapatma sırasını kontrol ederek yeni dağıtım sırasında aktif runner’lara işlerini bitirmeleri için zaman tanıyan shutdown akışı
  • İç implementasyon ayrıntıları ayrı bir yazıda devam edecek; şimdilik flame source incelenebilir

Mevcut durum ve sonraki adımlar

  • Elixir FLAME library’si henüz erken aşamada olsa da şimdi denenebilir
  • İleride daha gelişmiş pool büyütme teknikleri ve Elixir implementasyon yöntemine dair derinlemesine bir analiz planlanıyor
  • FLAME desenini başka dillerde uygulamaya yönelik tartışmalar da mümkün

1 yorum

 
GN⁺ 2023-12-08
Hacker News yorumları
  • Son 4 yılda 100’den fazla Lambda fonksiyonundan oluşan bir uygulamanın acısını ve karmaşıklığını yaşamış biri olarak, bu yazının FaaS sunucusuz mimarinin dezavantajlarını tam isabetle anlattığını düşünüyorum
    Başta bu dezavantajlar pek görünmüyor. Aksine, kullanım düşükse neredeyse ücretsiz olması ve neredeyse hiç bakım gerektirmemesi gibi avantajlar çok belirgin
    Ancak daha sonra Lambda iş akışları birbirine dolanıp karşılıklı bağımlılıklar yüzünden giderek katılaşınca, keşke monolite geçip birkaç yüz dolar daha harcayarak kendimiz yönetseydik diye pişman oluyorsunuz. Bugünlerde fly.io gibi yerlerle bu maliyet daha da düşük olabilir
    Elixir kullanmıyorsanız ne olacağını merak ediyorum

    • Hevesli geliştiricilerin neredeyse her tür süreç ya da mimariyi yaklaşık 18 ay boyunca işler halde tutabildiği örüntüsünü sürekli gördüm; artık bir tür kural ya da yasa gibi geliyor
      İşler kötüleşmeye başladığında genelde yeni iş aramanın zamanı da gelmiş oluyor. Özellikle işe girdikten yaklaşık 1 yıl sonra kendi getirdiğiniz süreçten artık pişmanlık duyuyorsanız bu daha da geçerli. Kötü yöneticilerde, berbat “birim testlerinde”, Scrum’da vb. bunu defalarca gördüm
      Yine de insanların iş yerinde hissettikleri rahatsızlığın nedenini net biçimde fark edip etmediğini, yoksa bunu belirsiz bir “artık ayrılma zamanı” hissi olarak mı aldığını bilmiyorum. Rahatsız edici şeye ad koymaya çalışınca çok tepki aldım; Good to Great’i okuduktan sonra bununla ilgili duygusal yıpranmam epey azaldı. Kimse “ah, bu benim davranışlarımın sonucuymuş” demek istemiyor
      Bakımını yaptığım Rube Goldberg tarzı sistemi fiilen yaratan kişiler ilk ayrılanlar oldu. O geminin kaptanı bir meslektaşıma motorumuzu açık kaynak yapsak nasıl olur diye sormuş; meslektaşım da zaten var olan ve daha iyi bir tekerleği yeniden icat eden bir sistemi kimsenin kullanmak istemeyeceğini söylemişti. O kişi 3-4 ay içinde kendi isteğiyle ayrıldı
    • Herhangi bir dilde bu sorunu çözebilecek bir şey geliştiriyoruz. Şu anda TypeScript SDK var, Java üzerinde de çalışıyoruz
      Lambda’ların birbirini çağırabildiği olağan hizmet odaklı kod yazabiliyorsanız, uygulamayı yüzlerce kısa çalışan parçaya bölmek zorunda kalmazsınız. Ancak bekleme süresi için de ücret ödemeniz gerekiyorsa bu mümkün olmaz. Lambda giriş/çıkış beklerken yürütmeyi askıya alabiliyorsa sorun çözülür. Bu yüzden dayanıklı yürütmenin (durable execution) yanıt olabileceğini düşünüyorum
      Son birkaç haftadır bunu gösteren bir yazı yazıyordum: https://restate.dev/blog/suspendable-functions-make-lambda-t...
    • Yazının bir bölümünde Elixir dışındaki FLAME de ele alınmıştı. Özetle, makul bir eşzamanlılık modeli olan dillerde genel olarak uygulanabilir bir desen
      Yakalanan değişkenlerin serileştirilebildiği fonksiyonlar gibi Elixir’de bedavaya gelen tüm kullanım kolaylıklarını elde etmek zor olabilir; ama JavaScript gibi dillerde, bir closure ile sarmalamak yerine modülün yürütme kısmını yeni bir dosyaya taşımak gibi bir yöntemle bunun %90’ına yaklaşılabilir gibi geliyor
      FLAME kütüphanesini uygulayan kişinin havuzlama, izleme ve uzak iletişim kısımlarını da yazması gerekir. Elixir dağıtık mesajlaşma ve izleme tarafında pek çok şeyi bedavaya sağlıyor. Süreç yerleştirmeyle ilgili özellikler de pratikte Elixir’e özgü
    • Sadece 12 Lambda varken bile katlanması zordu. Asıl uygulamayı bakım ya da dağıtımı pek düşünmeyen biri yapmıştı ve kod her yere kopyala-yapıştır edilmişti
      Sonunda tek bir Lambda’nın birden fazla endpoint’i işlediği şişman Lambda monolitine geçtik
    • Cold start’a çok takılmıyorsanız ya da yönetebiliyorsanız Lambda’da da monolit oluşturabilirsiniz
      Başka bir deyişle, monolite geçerken AWS maliyetlerini de minimumda tutabilirsiniz. İkisinden birini seçmek zorunda olduğunuz bir durum değil
      Şu sıralar asp.net kullanıyorum; optimize edilmiş EF modeli dahil ready-to-run olarak dağıtılan oldukça büyük bir uygulama bile görece hızlı başlıyor
  • Yazının yazarıyım. Sonunda yayımlayabildiğim için mutluyum; sorularınız varsa yanıtlarım. Umarım birkaç kişi FLAME desenini JavaScript, Go ve başka dillerde uygulamaya koymak için yeterince motive olmuştur

    • İyi görünüyor. Umarım Microsoft bunu fark eder. Azure Functions’ta güvenlik ayarları ve dağıtım çok karmaşık; ayrıca ne tür kod çalıştırmak istediğiniz konusunda tuhaf varsayımları var
    • En doğal uygulama JVM’deki vert.x gibi bir şey olur gibi geliyor
      Zaten bir event bus üzerinde reaktif ölçekleme, Future’lar ve coroutine’ler üzerinden asenkron yürütmeyi ele alan mekanizmalar var; küme genelinde veri serileştirme ve dağıtımı da destekliyor. Birkaç popüler dil için event bus istemcileri de var, dolayısıyla birden fazla dili karıştırarak uygulama oluşturmak mümkün olabilir
    • Abartıyı biraz azaltmak iyi olurdu
      Problemi “...ölümden beter bir kader” gibi sunup, çözümü de o kadar kolay ve acısız gösterirseniz ki başka yaklaşımları bırakmayanlar aptal gibi görünürse, böyle yazılar kolayca saf satış yazısı olarak görülür. Bu, her derde deva satan şarlatanların yöntemi
      Yazının başında problemin kendisi iyi yakalanmış; çok daha az duygusal, nesnel bir karşılaştırma olsaydı, daha iyi bir yaklaşımı merak eden insanlarda daha az itki yaratırdı
      Yazının asıl içeriği ilginçti, ama anlatım tarzı beni uzaklaştırdı. Bunu yapıcı geri bildirim olarak almanı isterim
    • Yazı ve video güzel, kavram da çok ilginç. JavaScript uygulamasını merakla bekliyorum ama kolay görünmüyor
      Ayrıca ffmpeg.fly.dev’i kapmış olduğum için çok az da olsa kendimi suçlu hissettim
    • Bunun, Sidekiq’in arka plan işlerini çalıştırmak için Rails kod tabanını örneklemesinden temelde nasıl farklı olduğunu merak ediyorum
  • “Mevcut uygulama kodunun herhangi bir bölümünü bir fonksiyonla sarmaladığınızı ve bunun otomatik ölçeklendiğini, o kod bloğunun da uygulamanın geçici bir kopyasında çalıştığını hayal edin” kısmı ilginç
    fork’un yaptığı şeyin sunucusuz için yapılmış hali gibi geliyor. Harika iş

  • Birkaç yıl önce fiilen bunu yapan bir servis kullanmıştım. PiCloud ne yazık ki Dropbox tarafından satın alındı, ama ondan önce işleri şeffaf biçimde worker’lara dağıtan tam da böyle bir modele sahipti. Kodu paketleyip worker üzerinde çalıştırıyordu.
    Örnek burada. Tam olarak aynı model olduğunu görebilirsiniz: https://github.com/picloud/basic-examples/blob/master/exampl...
    Elixir hiç kullanmadım ama onlarca yıl önce Erlang kullanmıştım; BEAM de temelde çok değişmemiş gibi görünüyor. Tasarımın temel parçalarından biri olduğu için bu tür işler için çok daha uygun olabilir. Yine de tamamen bedava öğle yemeği değil; bekleme sırasında ana sürecin ölme ihtimali var gibi geliyor

  • Genel argümana katılıyorum. Biz https://www.windmill.dev tarafında farklı bir yaklaşım seçtik: soyutlama birimini konteyner düzeyi değil, kaynak kod düzeyi olarak görüyoruz.
    main fonksiyonunu ve import’ları parse edip argümanları ve bağımlılıkları çıkarıyor, ardından kodu istenen runtime’da (TypeScript, Python, Go, Bash) olduğu gibi çalıştırıyoruz. Asıl püf noktası, cache’i verimli yöneterek import’lardan bağımsız olarak worker’ın her zaman sıcak kalmasını sağlamak.
    Bu yöntem kod tabanına FLAME kadar entegre değil, ama hedef kullanıcı kitlesi farklı. Bizim kullanıcılarımız karmaşık workflow’ları, cron işlerini veya otomatik oluşturulmuş UI eklenmiş tek seferlik script’leri sıfırdan oluşturuyor.
    FLAME’de tüm context’in snapshot’ı alınıp hedef VM’de yeniden geri yükleniyor gibi görünüyor. Diğer bir yaklaşım ise gerekli context ile gerekli olmayanı belirtmeye yarayan bir söz dizimi getirip yalnızca minimumu yüklemek. Mevcut kod tabanlarıyla Windmill’i daha iyi entegre etmek ve HTTP çağrılarına bağımlı olmamak için şu anda bunu araştırıyoruz

    • FLAME’de gerçekte olan şey tam olarak bu değil. FLAME yalnızca BEAM’in yerleşik clustering özelliği ile uzak node’da bir fonksiyonu çağırıyor.
      Bu süreçte yalnızca gereken context’in gönderilmesi örtük olarak hallediliyor. Yazıda da şöyle açıklanıyor: “FLAME.call bir runner pool adı ve bir fonksiyon alır. Sonra tüm uygulamanın yeni bir kopyasını bulur ya da başlatır ve fonksiyonu orada çalıştırır. Fonksiyonun closure olarak yakaladığı değişkenler, örneğin %Video{} struct’ı ve interval, otomatik olarak birlikte aktarılır”
    • Fazladan bir w girmiş. Arayanlar için URL burada: https://www.windmill.dev/
      Projenin hedefini seviyorum. Windmill’in daha iyi bir açık kaynak Retool/Airtable alternatifi olmasını gerçekten dört gözle bekliyorum
  • “FLAME’de geliştirme ve test runner’ları yerel backend’de olduğu gibi çalışır” kısmını sevdim. Yerel geliştirme deneyimi iyi olan serverless, güzelmiş

    • Aynen. Serverless’ı sevmeme nedenlerimden biri, bir monolit çalıştırmaya kıyasla yerel geliştirme deneyiminin çok daha kötü olması
  • “Sonra tüm uygulamanın yeni bir kopyasını bulur veya başlatır ve o fonksiyon orada çalıştırılır” ise, her Flame.call için tüm uygulama süreci baştan başlatılıp çalışma bağlamı içine mi kopyalanıyor?
    Ölçeklenebilirlik açısından çok basit bir çözüm, ama dezavantajları da olabilir gibi.
    Uygulama başlangıç süresi 10 ms artarsa, uygulamadaki her Flame.call noktasına 10 ms eklenmiş olur; bellek için de benzeri geçerli olabilir.
    Bu sistemi kullanırken bu kaygıların dikkate alınması gerekir gibi

    • Yazının ilerleyen kısmındaki FLAME.Pool bunu ele alıyor. Runner’lar pool’lanıyor; istediğiniz süre boyunca ayarlanabilir biçimde sıcak tutuluyor, sonra idle duruma iniyor.
      Yük altındayken pool zaten sıcak olduğundan cold start maliyeti neredeyse hiç ödenmiyor. Sırada Elixir kütüphanesine daha gelişmiş pool büyütme teknikleri de ekleniyor; böylece dolu bir runner’a denk gelip yeni bir cold start yapmak da önlenebilecek.
      Sıcak runner’larda tek overhead, parent ile child arasındaki gecikme. Aynı veri merkezinde olmaları gerektiğinden 1 ms ya da daha az olmalı
  • Harika. https://www.inngest.com/ üzerinde yaptığımız şeyin çok hafif bir Elixir’e özel sürümü gibi hissettiriyor.
    İkisinin de mevcut kodu bir şeyle sarmalayıp serverless function’larda kullanılabilir hale getirmesi ve özünde uzak RPC olarak çağrılabilir kılması benzer.
    Bu tür kodlar çoğu zaman imperatif adımlar dizisi olarak çalışır. Her adım ek bir Lambda olarak seri veya paralel çalıştırılabilir. Ancak adımlar arasında değişkenlerde yakalanmış örtük bir durum vardır. Bu yüzden fonksiyon bir workflow’a dönüşür. Inngest modelinde bu durum yakalanır ve dayanıklılık sağlamak için fonksiyona yeniden enjekte edilir.
    Dayanıklılık açısından bu tür süreçler queue temelli olmalı. Bu modelin güzel yanı queue’ların ucuz olması. Queue’yu tek satır kod kadar ucuz hale getirirseniz her şey kolaylaşır. Her geliştirici altyapıyı düşünmeden güvenilir kod yazabilir.
    İzleme ve gözlemlenebilirlik de önemli. Dead letter queue’lar gerçekten berbat; hata veren fonksiyonları veya adımları yönetebilmek ve yeniden çalıştırabilmek gerekir.
    FLAME ile Inngest arasında farklar da var. Inngest queue tabanlı, event-driven ve herhangi bir dilden HTTP ile sunulabilir. Inngest durumu dışarıda sakladığı için Elixir ile bir workflow yazıp sonra TypeScript ile yeniden yazıp dağıtsanız bile, çalışmakta olan fonksiyon CRIU’ya benzer şekilde backend dilleri arasında canlı taşınabilir.
    Event-driven yaklaşımda akış kontrolü de mümkün. Debounce, batch, throttling, fan-out; herhangi bir runtime veya dilde ele alınabilir. Örneğin Fly üzerindeki bir Elixir uygulaması event gönderip TypeScript + Lambda’da bir fonksiyonun çalışmasını sağlayabilir.
    FLAME’in nereye gideceğini merakla bekliyorum. Hedeflerde benzer kısımlar olduğunu düşünüyorum

    • Inngest güzel bir servis gibi görünüyor. Yazıda işleyiciler, dayanıklılık ve retry’lar da ele alınmıştı.
      Elixir’de dayanıklılık, retry ve workflow gerektiğinde genelde Oban kullanılır; burada da böyle yapmaya devam edeceğiz. Oban işi FLAME’i çağırıp elastik yürütmeyi onun halletmesini sağlayacak
  • HN'nin dayattığı Amerikan tarzı başlık büyük/küçük harf kullanımından gerçekten nefret etmemin nedenlerinden biri bu. Serverless, büyük S'li şirket serverless.com'u yeniden düşünmek anlamına geliyormuş gibi görünüyor; küçük s'li ilkeyi yeniden düşünmek anlamına gelmiyor
    Ek olarak, birilerinin Serverless'ı yeniden düşünmesini isterdim

    • Büyük/küçük harf kullanımını HN'nin dayattığını değil, yazıyı gönderen kişinin belirlediğini sanıyorum
      https://sst.dev/'e bakıp bakmadığını bilmiyorum ama tam da bunu yapmışlar gibi görünüyor. Örneğin Live Lambda Development var; kodu buluta yükleyip dağıtımı beklemek zorunda kalmadan geri bildirim döngüsünü büyük ölçüde kısaltarak yerel geliştirmeyi gerçekten kolaylaştırıyor
  • Fikir oldukça hoş ve API de harika
    “Video transcoding gibi CPU-bound işler production'da tüm servisi hızla durma noktasına getirebilir” kısmı için, sadece CPU bazlı otomatik ölçekleme yapılamaz mı?

    • Yazının başlarında bu fikre değinmeye çalışmıştım. Bu yaklaşımın sorunu, yanlış çalışma düzeyinde ölçekleme yapması
      Belirli bir sıcak işi ele almak için web sunucusu da dahil tüm uygulamayı ölçeklemiş oluyorsunuz. İstediğimiz şey ve FaaS'e yönelmemizin nedeni, ince taneli elastik ölçekleme. Buradaki fikir, web sunucusu ya da worker ölçekleme düğmesine rastgele basıp iyi sonuç ummak yerine, mevcut uygulama kodu için bu ince taneli ölçeklemeyi mümkün kılmak
    • Hem doğru hem değil. İş yükünün geri kalanı çok fazla CPU gerektirmeyebilir. Bu performansa yalnızca bir iki iş yükü ihtiyaç duyabilir ve o işin başka işler tarafından geriye itilmesini istemeyebilirsiniz
      Ya da GPU gerekebilir
      Çekirdek servis için 1-2 sunucu yeterli olabilir, ancak günde belki bir kez gerçekleşen bir iş için gerektiğinde onlarca, yüzlerce, binlerce sunucuya ölçeklenmeniz gerekebilir