# Swift Distributed Actors: Dagitik Sistemlerde Swift
Swift 5.7 ile gelen distributed actor kavrami, dagitik sistemlerin gelistirilmesini kokten degistirdi. Ayni dilde hem mobil uygulama hem de dagitik backend servisi yazabilmek, Swift ekosisteminin en heyecan verici gelismelerinden biri. Bu rehberde distributed actor'lerin tum detaylarini, transport layer implementasyonunu ve production senaryolarini inceleyecegiz.
Onkosul: Bu rehberi takip etmek icin Swift Concurrency (async/await, actor) konularinda temel bilgiye sahip olmaniz gerekmektedir.
Icindekiler
- Distributed Actor Nedir?
- Local vs Distributed Actor
- Temel Kullanim
- Transport Layer
- Distributed Method Call
- Codable ve Serialization
- Cluster Yonetimi
- Hata Yonetimi
- Testing Stratejileri
- Production Ornekleri
- Sonuc ve Oneriler
1. Distributed Actor Nedir?
Normal bir actor sadece ayni process icinde calisir. distributed actor ise farkli makinelerde, farkli process'lerde calisan actor'ler arasinda iletisim kurmamizi saglar - sanki local bir fonksiyon cagiriyormusuz gibi.
Temel Farklar
Ozellik | Actor | Distributed Actor |
|---|---|---|
**Konum** | Ayni process | Farkli process/makine |
**Erisim** | Dogrudan | Network uzerinden |
**Hata** | Synchronous | throws (network hatasi) |
**Kimlik** | Reference | ActorID (serializable) |
**Transport** | Yok | Gerekli (custom/library) |
**Performans** | Hizli | Network latency |
**Isolation** | Compiler-enforced | Compiler + runtime |
**Serialization** | Gerekli degil | Codable zorunlu |
Neden Distributed Actors?
Geleneksel dagitik sistemlerde RPC (Remote Procedure Call) kullanirsiniz. Sorunlar:
- Farkli serialization formatlari
- Manuel hata yonetimi
- Tip guvenligi yok
- Interface tanimlamalari ayri dosyalarda
Distributed actors tum bunlari cozuyor: derleyici seviyesinde tip guvenligi, otomatik serialization ve transparan remote call'lar.
2. Local vs Distributed Actor
swift
1// Normal actor - sadece local2actor BankAccount {3 let id: String4 private var balance: Double = 05 6 init(id: String) {7 self.id = id8 }9 10 func deposit(_ amount: Double) {11 balance += amount12 }13 14 func getBalance() -> Double {15 return balance16 }17}18 19// Distributed actor - local VEYA remote20distributed actor DistributedBankAccount {21 typealias ActorSystem = ClusterSystem22 23 private var balance: Double = 024 25 distributed func deposit(_ amount: Double) {26 balance += amount27 }28 29 distributed func getBalance() -> Double {30 return balance31 }32 33 // distributed OLMAYAN fonksiyonlar sadece local erisim34 func internalAudit() -> AuditReport {35 // Bu fonksiyon remote'dan cagrilamaz36 AuditReport(balance: balance, timestamp: .now)37 }38}Easter Egg
Gizli bir bilgi buldun!
Bu bölümde gizli bir bilgi var. Keşfetmek ister misin?
3. Temel Kullanim
swift
1import Distributed2 3// 1. Actor System tanimla4distributed actor GamePlayer {5 typealias ActorSystem = ClusterSystem6 7 let username: String8 private var score: Int = 09 private var level: Int = 110 11 init(username: String, actorSystem: ActorSystem) {12 self.actorSystem = actorSystem13 self.username = username14 }15 16 distributed func addScore(_ points: Int) {17 score += points18 if score >= level * 1000 {19 level += 120 }21 }22 23 distributed func getStats() -> PlayerStats {24 PlayerStats(25 username: username,26 score: score,27 level: level28 )29 }30 31 distributed func challenge(_ opponent: GamePlayer) async throws -> ChallengeResult {32 let myStats = getStats()33 let opponentStats = try await opponent.getStats()34 35 // Basit bir challenge mekanigi36 if myStats.score > opponentStats.score {37 return .won38 } else if myStats.score < opponentStats.score {39 return .lost40 } else {41 return .draw42 }43 }44}45 46struct PlayerStats: Codable, Sendable {47 let username: String48 let score: Int49 let level: Int50}51 52enum ChallengeResult: Codable, Sendable {53 case won, lost, draw54}Distributed Fonksiyon Kurallari
- Tum parametre ve donus turleri
Codable & Sendableolmali - Her distributed fonksiyon
throwsolarak ele alinir (network hatasi) - Remote cagirilarda
awaitzorunludur (local olsa bile) - Property'ler distributed olamaz, fonksiyon kullanin
4. Transport Layer
Distributed actors, bir DistributedActorSystem uzerinden haberlesir. Bu transport layer'i kendiniz yazabilir veya hazir kutuphaneler kullanabilirsiniz.
swift
1// Basit bir in-memory transport ornegi (test icin ideal)2final class LocalTestingActorSystem: DistributedActorSystem {3 typealias ActorID = String4 typealias InvocationEncoder = LocalInvocationEncoder5 typealias InvocationDecoder = LocalInvocationDecoder6 typealias SerializationRequirement = Codable7 typealias ResultHandler = LocalResultHandler8 9 private var actors: [String: any DistributedActor] = [:]10 11 func resolve<Act>(id: ActorID, as actorType: Act.Type) throws -> Act?12 where Act: DistributedActor, ActorID == Act.ID {13 actors[id] as? Act14 }15 16 func assignID<Act>(_ actorType: Act.Type) -> ActorID17 where Act: DistributedActor, ActorID == Act.ID {18 UUID().uuidString19 }20 21 func actorReady<Act>(_ actor: Act)22 where Act: DistributedActor, ActorID == Act.ID {23 actors[actor.id] = actor24 }25 26 func resignID(_ id: ActorID) {27 actors.removeValue(forKey: id)28 }29 30 func makeInvocationEncoder() -> InvocationEncoder {31 LocalInvocationEncoder()32 }33 34 func remoteCall<Act, Err, Res>(35 on actor: Act,36 target: RemoteCallTarget,37 invocation: inout InvocationEncoder,38 throwing: Err.Type,39 returning: Res.Type40 ) async throws -> Res41 where Act: DistributedActor,42 Err: Error,43 Res: SerializationRequirement {44 fatalError("Local-only system, remote call desteklenmez")45 }46 47 func remoteCallVoid<Act, Err>(48 on actor: Act,49 target: RemoteCallTarget,50 invocation: inout InvocationEncoder,51 throwing: Err.Type52 ) async throws53 where Act: DistributedActor, Err: Error {54 fatalError("Local-only system, remote call desteklenmez")55 }56}Transport Secenekleri
Transport | Kullanim Alani | Avantaj | Dezavantaj |
|---|---|---|---|
**WebSocket** | Realtime uygulamalar | Dusuk latency | Baglanti yonetimi |
**HTTP/2** | REST-benzeri servisler | Yaygin destek | Overhead |
**gRPC** | Mikroservisler | Yuksek performans | Karmasiklik |
**Local (test)** | Unit test | Hizli, basit | Sadece test |
**Custom TCP** | Oyun serverlari | Tam kontrol | Cok is |
5. Distributed Method Call Mekanigi
Bir distributed fonksiyon cagrildiginda arka planda neler olur:
- Serialization: Parametreler
Codableile serialize edilir - Routing: ActorSystem, hedef actor'un konumunu bulur
- Transport: Serialized veri network uzerinden gonderilir
- Deserialization: Hedef tarafta parametreler deserialize edilir
- Execution: Fonksiyon local olarak calistirilir
- Response: Sonuc ayni yoldan geri doner
6. Codable ve Serialization
Distributed actor'lerdeki tum paylasilan tipler Codable & Sendable olmalidir.
swift
1// Tum distributed fonksiyon parametreleri ve donus turleri2// Codable & Sendable olmak zorunda3 4struct GameMove: Codable, Sendable {5 let playerId: String6 let position: Position7 let timestamp: Date8 let moveType: MoveType9}10 11struct Position: Codable, Sendable {12 let x: Int13 let y: Int14}15 16enum MoveType: String, Codable, Sendable {17 case attack18 case defend19 case move20 case special21}22 23// Distributed actor'de kullanim24distributed actor GameSession {25 typealias ActorSystem = ClusterSystem26 27 private var moves: [GameMove] = []28 private var players: [String: GamePlayer] = [:]29 30 distributed func makeMove(_ move: GameMove) throws -> MoveResult {31 guard players[move.playerId] != nil else {32 throw GameError.playerNotFound33 }34 35 // Hareket validasyonu36 guard isValidMove(move) else {37 throw GameError.invalidMove38 }39 40 moves.append(move)41 return MoveResult(accepted: true, newState: currentState())42 }43 44 distributed func getHistory() -> [GameMove] {45 return moves46 }47 48 private func isValidMove(_ move: GameMove) -> Bool {49 // Oyun kurallari kontrolu50 return true51 }52 53 private func currentState() -> GameState {54 GameState(moveCount: moves.count, lastMove: moves.last)55 }56}57 58struct MoveResult: Codable, Sendable {59 let accepted: Bool60 let newState: GameState61}62 63struct GameState: Codable, Sendable {64 let moveCount: Int65 let lastMove: GameMove?66}67 68enum GameError: Error, Codable, Sendable {69 case playerNotFound70 case invalidMove71 case sessionExpired72}7. Cluster Yonetimi
Production ortaminda birden fazla node'un birlikte calismasi gerekir. Cluster yonetimi, node discovery, health check ve failover konularini kapsar.
Cluster Mimarisi
- Leader Election: Bir node cluster'i yonetir
- Membership: Node'larin katilimi ve ayrilmasi
- Health Check: Duzenli kalp atisi kontrolu
- Failover: Ariza durumunda otomatik gecis
8. Hata Yonetimi
Dagitik sistemlerde hata kacinilmazdir. Network kesintisi, timeout, node cokmeleri...
swift
1// Retry mekanizmasi ile distributed call2func fetchPlayerStatsWithRetry(3 player: GamePlayer,4 maxRetries: Int = 35) async throws -> PlayerStats {6 var lastError: Error?7 8 for attempt in 1...maxRetries {9 do {10 return try await player.getStats()11 } catch {12 lastError = error13 // Exponential backoff14 let delay = UInt64(pow(2.0, Double(attempt))) * 100_000_00015 try await Task.sleep(nanoseconds: delay)16 }17 }18 19 throw lastError ?? DistributedSystemError.unknown20}21 22enum DistributedSystemError: Error {23 case unknown24 case nodeUnreachable25 case timeout26 case serializationFailed27}9. Testing Stratejileri
Distributed actor'leri test etmek icin local actor system kullanin.
Test Ornegi
- Unit test: LocalTestingActorSystem ile
- Integration test: Gercek transport ile
- Chaos testing: Network hatasi simulasyonu
10. Production Ornekleri
Kullanim Alanlari
Senaryo | Aciklama | Fayda |
|---|---|---|
**Chat uygulamasi** | Her kullanici bir actor | Dogal isolation |
**Oyun serveri** | Her session bir actor | State yonetimi |
**IoT gateway** | Her cihaz bir actor | Olceklenebilirlik |
**Mikroservis** | Her servis bir actor cluster | Tip guvenligi |
**Edge computing** | Cihaz-server iletisimi | Transparan RPC |
11. Sonuc ve Oneriler
Swift Distributed Actors, dagitik sistem gelistirmeyi dramatik sekilde basitlestiriyor. Ancak henuz ekosistem olgunlasmadi - production kullanimi icin dikkatli olun.
Aksiyon Plani
- Swift Concurrency temellerini ogrenmeden baslamayin
- Kucuk bir projede local actor system ile deneyin
- Transport layer secimini kullanim senaryonuza gore yapin
- Hata yonetimi ve retry mekanizmasini mutlaka ekleyin
- Monitoring ve logging altyapisini kurun
ALTIN İPUCU
Bu yazının en değerli bilgisi
Bu ipucu, yazının en önemli çıkarımını içeriyor.
Okuyucu Ödülü
Tebrikler! Bu yazıyı sonuna kadar okuduğun için sana özel bir hediyem var:

