#FilesystemAccess
Just found out Muse can download its whole filesystem and even leaks internal docs on prompt injection. If you’re into AI coding agents or Linux VMs, this security hole is a must‑read. Dive into the details! #MetaMuse #FilesystemAccess #PromptInjection

🔗 aidailypost.com/news/muse-al...
September 24, 2026 at 8:23 PM
Avoid Massive Actors with Empty Global Actors
The most common way to think about actors is similar to structs and classes. They are a type with properties or methods defined. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } } This is fine. But this can lead to issues as the codebase grows and logic changes. This article will show a case where an actor with no properties or methods defined (an Empty Global Actor) is a valid option. This can help us remove Massive Actors from our code. ## Background In my work transitioning apps to Swift Concurrency I’ve wanted to use functionality similar to MainActor, but with a custom actor. @CustomActor class SomeClass {} or class SomeIsolatedType { @CustomActor func doWorkOnOtherActor() } This has led me to create Global Actors with no custom functionality. This isn’t how most of us are thinking about actors, but it allows us to do some powerful things. 1. Avoid dumping too much logic into an Actor. The removes the threat of Massive Actors. And leaves us more options as the codebase evolves. 2. Separate the logic in our code from how it is run. This is a powerful technique I’ve used for years to allow code I work with to scale. Let’s talk about an example of where we could use an empty Global Actor. ## Use Case - Restrict Access to File System File access is a classic example of code that is not thread safe. The runtime will gladly modify the same file from multiple threads. This can lead hard to reproduce bugs. Actors in Swift Concurrency provide a way to enforce safe file system access at compile time. ### Possible Approach 1 - add methods to the FileSystemActor One approach for solving this with Swift Concurrency is to add the functionality to an actor. This matches how most of us think about creating actors. And how Apple shows actors being used in their documentation. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } } This will work ok for basic functionality. But has the downside of forcing all file system functionality in to exist in the same type. Even methods that are unrelated and should be broken out into new types. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } func unrelatedFileWrite() { // ... } func thisShouldntBeInTheSameType() { // ... } } #### Downside - Massive Actors **This can lead us to the Massive Actor problem.** ### Possible Approach 2 - bring in the extensions A tempting alternative is to break up large types by using extensions extension FileSystemAccess { func unrelatedFileWrite() { // ... } func thisShouldntBeInTheSameType() { // ... } } **This doesn’t solve anything.** It may split up the functionality into new source files. But the types are still bigger than needed. And the approach has the same downsides as the Massive Actor. Devs do this hoping smaller files make code more readable. But usually it makes things more confusing because you have to look to a new file to understand the behavior the type is responsible for. Neither of these are good solutions for complex functionality. But may work ok for simple use cases. ## Solution - use an Global Actor This allows you to annotate classes, properties and methods with a custom actor. This requires a Global Actor to be defined. @globalActor actor FileSystemActor { static let shared = FileSystemActor() } This allows us to annotate our classes and structs with a custom actor @FileSystemActor class SomeClass { let fileSystem = FileSystemAccess() func readFromFile(urlString: String) async { await fileSystem.readFromFile(urlString: urlString) } } This also works for properties class SomeClass { @FileSystemActor let fileSystem = FileSystemAccess() } and methods class SomeClass { @FileSystemActor func accessSomething() { } } For our use case, the actor doesn’t need any functionality defined at all. It’s an Empty Global Actor. ### Benefits of using Empty Global Actors 1. It separates the logic from how it is run. A win! 2. They allow us to isolate functions in legacy code. We know you didn’t mean to have file access in your ViewController, but now you have a workaround until you can make a more proper fix. #### Aspect oriented programming? Astute observers have been noting that property wrappers in Swift allow us to do things described in Aspect Oriented Programming. Splitting out functionality into a specific Actor is a valid way to keep different concerns separate in our code. In my work I commonly push back on any solutions that introduce more global variables into existence. But this provides enough benefits to justify it. ### What do you think? Would this work for code you’re working with? What are some other use cases for Empty Global Actors?
jaimzuber.com
January 28, 2025 at 3:53 AM
Avoid Massive Actors with Empty Global Actors
The most common way to think about actors is similar to structs and classes. They are a type with properties or methods defined. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } } This is fine. But this can lead to issues as the codebase grows and logic changes. This article will show a case where an actor with no properties or methods defined (an Empty Global Actor) is a valid option. This can help us remove Massive Actors from our code. ## Background In my work transitioning apps to Swift Concurrency I’ve wanted to use functionality similar to MainActor, but with a custom actor. @CustomActor class SomeClass {} or class SomeIsolatedType { @CustomActor func doWorkOnOtherActor() } This has led me to create Global Actors with no custom functionality. This isn’t how most of us are thinking about actors, but it allows us to do some powerful things. 1. Avoid dumping too much logic into an Actor. The removes the threat of Massive Actors. And leaves us more options as the codebase evolves. 2. Separate the logic in our code from how it is run. This is a powerful technique I’ve used for years to allow code I work with to scale. Let’s talk about an example of where we could use an empty Global Actor. ## Use Case - Restrict Access to File System File access is a classic example of code that is not thread safe. The runtime will gladly modify the same file from multiple threads. This can lead hard to reproduce bugs. Actors in Swift Concurrency provide a way to enforce safe file system access at compile time. ### Possible Approach 1 - add methods to the FileSystemActor One approach for solving this with Swift Concurrency is to add the functionality to an actor. This matches how most of us think about creating actors. And how Apple shows actors being used in their documentation. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } } This will work ok for basic functionality. But has the downside of forcing all file system functionality in to exist in the same type. Even methods that are unrelated and should be broken out into new types. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } func unrelatedFileWrite() { // ... } func thisShouldntBeInTheSameType() { // ... } } #### Downside - Massive Actors **This can lead us to the Massive Actor problem.** ### Possible Approach 2 - bring in the extensions A tempting alternative is to break up large types by using extensions extension FileSystemAccess { func unrelatedFileWrite() { // ... } func thisShouldntBeInTheSameType() { // ... } } **This doesn’t solve anything.** It may split up the functionality into new source files. But the types are still bigger than needed. And the approach has the same downsides as the Massive Actor. Devs do this hoping smaller files make code more readable. But usually it makes things more confusing because you have to look to a new file to understand the behavior the type is responsible for. Neither of these are good solutions for complex functionality. But may work ok for simple use cases. ## Solution - use an Global Actor This allows you to annotate classes, properties and methods with a custom actor. This requires a Global Actor to be defined. @globalActor actor FileSystemActor { static let shared = FileSystemActor() } This allows us to annotate our classes and structs with a custom actor @FileSystemActor class SomeClass { let fileSystem = FileSystemAccess() func readFromFile(urlString: String) async { await fileSystem.readFromFile(urlString: urlString) } } This also works for properties class SomeClass { @FileSystemActor let fileSystem = FileSystemAccess() } and methods class SomeClass { @FileSystemActor func accessSomething() { } } For our use case, the actor doesn’t need any functionality defined at all. It’s an Empty Global Actor. ### Benefits of using Empty Global Actors 1. It separates the logic from how it is run. A win! 2. They allow us to isolate functions in legacy code. We know you didn’t mean to have file access in your ViewController, but now you have a workaround until you can make a more proper fix. #### Aspect oriented programming? Astute observers have been noting that property wrappers in Swift allow us to do things described in Aspect Oriented Programming. Splitting out functionality into a specific Actor is a valid way to keep different concerns separate in our code. In my work I commonly push back on any solutions that introduce more global variables into existence. But this provides enough benefits to justify it. ### What do you think? Would this work for code you’re working with? What are some other use cases for Empty Global Actors?
jaimzuber.com
January 23, 2025 at 3:53 AM
Avoid Massive Actors with Empty Global Actors
The most common way to think about actors is similar to structs and classes. They are a type with properties or methods defined. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } } This is fine. But this can lead to issues as the codebase grows and logic changes. This article will show a case where an actor with no properties or methods defined (an Empty Global Actor) is a valid option. This can help us remove Massive Actors from our code. ## Background In my work transitioning apps to Swift Concurrency I’ve wanted to use functionality similar to MainActor, but with a custom actor. @CustomActor class SomeClass {} or class SomeIsolatedType { @CustomActor func doWorkOnOtherActor() } This has led me to create Global Actors with no custom functionality. This isn’t how most of us are thinking about actors, but it allows us to do some powerful things. 1. Avoid dumping too much logic into an Actor. The removes the threat of Massive Actors. And leaves us more options as the codebase evolves. 2. Separate the logic in our code from how it is run. This is a powerful technique I’ve used for years to allow code I work with to scale. Let’s talk about an example of where we could use an empty Global Actor. ## Use Case - Restrict Access to File System File access is a classic example of code that is not thread safe. The runtime will gladly modify the same file from multiple threads. This can lead hard to reproduce bugs. Actors in Swift Concurrency provide a way to enforce safe file system access at compile time. ### Possible Approach 1 - add methods to the FileSystemActor One approach for solving this with Swift Concurrency is to add the functionality to an actor. This matches how most of us think about creating actors. And how Apple shows actors being used in their documentation. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } } This will work ok for basic functionality. But has the downside of forcing all file system functionality in to exist in the same type. Even methods that are unrelated and should be broken out into new types. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } func unrelatedFileWrite() { // ... } func thisShouldntBeInTheSameType() { // ... } } #### Downside - Massive Actors **This can lead us to the Massive Actor problem.** ### Possible Approach 2 - bring in the extensions A tempting alternative is to break up large types by using extensions extension FileSystemAccess { func unrelatedFileWrite() { // ... } func thisShouldntBeInTheSameType() { // ... } } **This doesn’t solve anything.** It may split up the functionality into new source files. But the types are still bigger than needed. And the approach has the same downsides as the Massive Actor. Devs do this hoping smaller files make code more readable. But usually it makes things more confusing because you have to look to a new file to understand the behavior the type is responsible for. Neither of these are good solutions for complex functionality. But may work ok for simple use cases. ## Solution - use an Global Actor This allows you to annotate classes, properties and methods with a custom actor. This requires a Global Actor to be defined. @globalActor actor FileSystemActor { static let shared = FileSystemActor() } This allows us to annotate our classes and structs with a custom actor @FileSystemActor class SomeClass { let fileSystem = FileSystemAccess() func readFromFile(urlString: String) async { await fileSystem.readFromFile(urlString: urlString) } } This also works for properties class SomeClass { @FileSystemActor let fileSystem = FileSystemAccess() } and methods class SomeClass { @FileSystemActor func accessSomething() { } } For our use case, the actor doesn’t need any functionality defined at all. It’s an Empty Global Actor. ### Benefits of using Empty Global Actors 1. It separates the logic from how it is run. A win! 2. They allow us to isolate functions in legacy code. We know you didn’t mean to have file access in your ViewController, but now you have a workaround until you can make a more proper fix. #### Aspect oriented programming? Astute observers have been noting that property wrappers in Swift allow us to do things described in Aspect Oriented Programming. Splitting out functionality into a specific Actor is a valid way to keep different concerns separate in our code. In my work I commonly push back on any solutions that introduce more global variables into existence. But this provides enough benefits to justify it. ### What do you think? Would this work for code you’re working with? What are some other use cases for Empty Global Actors?
jaimzuber.com
January 6, 2025 at 3:58 AM
Avoid Massive Actors with Empty Global Actors
The most common way to think about actors is similar to structs and classes. They are a type with properties or methods defined. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } } This is fine. But this can lead to issues as the codebase grows and logic changes. This article will show a case where an actor with no properties or methods defined (an Empty Global Actor) is a valid option. This can help us remove Massive Actors from our code. ## Background In my work transitioning apps to Swift Concurrency I’ve wanted to use functionality similar to MainActor, but with a custom actor. @CustomActor class SomeClass {} or class SomeIsolatedType { @CustomActor func doWorkOnOtherActor() } This has led me to create Global Actors with no custom functionality. This isn’t how most of us are thinking about actors, but it allows us to do some powerful things. 1. Avoid dumping too much logic into an Actor. The removes the threat of Massive Actors. And leaves us more options as the codebase evolves. 2. Separate the logic in our code from how it is run. This is a powerful technique I’ve used for years to allow code I work with to scale. Let’s talk about an example of where we could use an empty Global Actor. ## Use Case - Restrict Access to File System File access is a classic example of code that is not thread safe. The runtime will gladly modify the same file from multiple threads. This can lead hard to reproduce bugs. Actors in Swift Concurrency provide a way to enforce safe file system access at compile time. ### Possible Approach 1 - add methods to the FileSystemActor One approach for solving this with Swift Concurrency is to add the functionality to an actor. This matches how most of us think about creating actors. And how Apple shows actors being used in their documentation. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } } This will work ok for basic functionality. But has the downside of forcing all file system functionality in to exist in the same type. Even methods that are unrelated and should be broken out into new types. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } func unrelatedFileWrite() { // ... } func thisShouldntBeInTheSameType() { // ... } } #### Downside - Massive Actors **This can lead us to the Massive Actor problem.** ### Possible Approach 2 - bring in the extensions A tempting alternative is to break up large types by using extensions extension FileSystemAccess { func unrelatedFileWrite() { // ... } func thisShouldntBeInTheSameType() { // ... } } **This doesn’t solve anything.** It may split up the functionality into new source files. But the types are still bigger than needed. And the approach has the same downsides as the Massive Actor. Devs do this hoping smaller files make code more readable. But usually it makes things more confusing because you have to look to a new file to understand the behavior the type is responsible for. Neither of these are good solutions for complex functionality. But may work ok for simple use cases. ## Solution - use an Global Actor This allows you to annotate classes, properties and methods with a custom actor. This requires a Global Actor to be defined. @globalActor actor FileSystemActor { static let shared = FileSystemActor() } This allows us to annotate our classes and structs with a custom actor @FileSystemActor class SomeClass { let fileSystem = FileSystemAccess() func readFromFile(urlString: String) async { await fileSystem.readFromFile(urlString: urlString) } } This also works for properties class SomeClass { @FileSystemActor let fileSystem = FileSystemAccess() } and methods class SomeClass { @FileSystemActor func accessSomething() { } } For our use case, the actor doesn’t need any functionality defined at all. It’s an Empty Global Actor. ### Benefits of using Empty Global Actors 1. It separates the logic from how it is run. A win! 2. They allow us to isolate functions in legacy code. We know you didn’t mean to have file access in your ViewController, but now you have a workaround until you can make a more proper fix. #### Aspect oriented programming? Astute observers have been noting that property wrappers in Swift allow us to do things described in Aspect Oriented Programming. Splitting out functionality into a specific Actor is a valid way to keep different concerns separate in our code. In my work I commonly push back on any solutions that introduce more global variables into existence. But this provides enough benefits to justify it. ### What do you think? Would this work for code you’re working with? What are some other use cases for Empty Global Actors?
jaimzuber.com
December 29, 2024 at 3:52 AM
Avoid Massive Actors with Empty Global Actors
The most common way to think about actors is similar to structs and classes. They are a type with properties or methods defined. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } } This is fine. But this can lead to issues as the codebase grows and logic changes. This article will show a case where an actor with no properties or methods defined (an Empty Global Actor) is a valid option. This can help us remove Massive Actors from our code. ## Background In my work transitioning apps to Swift Concurrency I’ve wanted to use functionality similar to MainActor, but with a custom actor. @CustomActor class SomeClass {} or class SomeIsolatedType { @CustomActor func doWorkOnOtherActor() } This has led me to create Global Actors with no custom functionality. This isn’t how most of us are thinking about actors, but it allows us to do some powerful things. 1. Avoid dumping too much logic into an Actor. The removes the threat of Massive Actors. And leaves us more options as the codebase evolves. 2. Separate the logic in our code from how it is run. This is a powerful technique I’ve used for years to allow code I work with to scale. Let’s talk about an example of where we could use an empty Global Actor. ## Use Case - Restrict Access to File System File access is a classic example of code that is not thread safe. The runtime will gladly modify the same file from multiple threads. This can lead hard to reproduce bugs. Actors in Swift Concurrency provide a way to enforce safe file system access at compile time. ### Possible Approach 1 - add methods to the FileSystemActor One approach for solving this with Swift Concurrency is to add the functionality to an actor. This matches how most of us think about creating actors. And how Apple shows actors being used in their documentation. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } } This will work ok for basic functionality. But has the downside of forcing all file system functionality in to exist in the same type. Even methods that are unrelated and should be broken out into new types. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } func unrelatedFileWrite() { // ... } func thisShouldntBeInTheSameType() { // ... } } #### Downside - Massive Actors **This can lead us to the Massive Actor problem.** ### Possible Approach 2 - bring in the extensions A tempting alternative is to break up large types by using extensions extension FileSystemAccess { func unrelatedFileWrite() { // ... } func thisShouldntBeInTheSameType() { // ... } } **This doesn’t solve anything.** It may split up the functionality into new source files. But the types are still bigger than needed. And the approach has the same downsides as the Massive Actor. Devs do this hoping smaller files make code more readable. But usually it makes things more confusing because you have to look to a new file to understand the behavior the type is responsible for. Neither of these are good solutions for complex functionality. But may work ok for simple use cases. ## Solution - use an Global Actor This allows you to annotate classes, properties and methods with a custom actor. This requires a Global Actor to be defined. @globalActor actor FileSystemActor { static let shared = FileSystemActor() } This allows us to annotate our classes and structs with a custom actor @FileSystemActor class SomeClass { let fileSystem = FileSystemAccess() func readFromFile(urlString: String) async { await fileSystem.readFromFile(urlString: urlString) } } This also works for properties class SomeClass { @FileSystemActor let fileSystem = FileSystemAccess() } and methods class SomeClass { @FileSystemActor func accessSomething() { } } For our use case, the actor doesn’t need any functionality defined at all. It’s an Empty Global Actor. ### Benefits of using Empty Global Actors 1. It separates the logic from how it is run. A win! 2. They allow us to isolate functions in legacy code. We know you didn’t mean to have file access in your ViewController, but now you have a workaround until you can make a more proper fix. #### Aspect oriented programming? Astute observers have been noting that property wrappers in Swift allow us to do things described in Aspect Oriented Programming. Splitting out functionality into a specific Actor is a valid way to keep different concerns separate in our code. In my work I commonly push back on any solutions that introduce more global variables into existence. But this provides enough benefits to justify it. ### What do you think? Would this work for code you’re working with? What are some other use cases for Empty Global Actors?
jaimzuber.com
December 22, 2024 at 3:52 AM
Avoid Massive Actors with Empty Global Actors
The most common way to think about actors is similar to structs and classes. They are a type with properties or methods defined. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } } This is fine. But this can lead to issues as the codebase grows and logic changes. This article will show a case where an actor with no properties or methods defined (an Empty Global Actor) is a valid option. This can help us remove Massive Actors from our code. ## Background In my work transitioning apps to Swift Concurrency I’ve wanted to use functionality similar to MainActor, but with a custom actor. @CustomActor class SomeClass {} or class SomeIsolatedType { @CustomActor func doWorkOnOtherActor() } This has led me to create Global Actors with no custom functionality. This isn’t how most of us are thinking about actors, but it allows us to do some powerful things. 1. Avoid dumping too much logic into an Actor. The removes the threat of Massive Actors. And leaves us more options as the codebase evolves. 2. Separate the logic in our code from how it is run. This is a powerful technique I’ve used for years to allow code I work with to scale. Let’s talk about an example of where we could use an empty Global Actor. ## Use Case - Restrict Access to File System File access is a classic example of code that is not thread safe. The runtime will gladly modify the same file from multiple threads. This can lead hard to reproduce bugs. Actors in Swift Concurrency provide a way to enforce safe file system access at compile time. ### Possible Approach 1 - add methods to the FileSystemActor One approach for solving this with Swift Concurrency is to add the functionality to an actor. This matches how most of us think about creating actors. And how Apple shows actors being used in their documentation. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } } This will work ok for basic functionality. But has the downside of forcing all file system functionality in to exist in the same type. Even methods that are unrelated and should be broken out into new types. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } func unrelatedFileWrite() { // ... } func thisShouldntBeInTheSameType() { // ... } } #### Downside - Massive Actors **This can lead us to the Massive Actor problem.** ### Possible Approach 2 - bring in the extensions A tempting alternative is to break up large types by using extensions extension FileSystemAccess { func unrelatedFileWrite() { // ... } func thisShouldntBeInTheSameType() { // ... } } **This doesn’t solve anything.** It may split up the functionality into new source files. But the types are still bigger than needed. And the approach has the same downsides as the Massive Actor. Devs do this hoping smaller files make code more readable. But usually it makes things more confusing because you have to look to a new file to understand the behavior the type is responsible for. Neither of these are good solutions for complex functionality. But may work ok for simple use cases. ## Solution - use an Global Actor This allows you to annotate classes, properties and methods with a custom actor. This requires a Global Actor to be defined. @globalActor actor FileSystemActor { static let shared = FileSystemActor() } This allows us to annotate our classes and structs with a custom actor @FileSystemActor class SomeClass { let fileSystem = FileSystemAccess() func readFromFile(urlString: String) async { await fileSystem.readFromFile(urlString: urlString) } } This also works for properties class SomeClass { @FileSystemActor let fileSystem = FileSystemAccess() } and methods class SomeClass { @FileSystemActor func accessSomething() { } } For our use case, the actor doesn’t need any functionality defined at all. It’s an Empty Global Actor. ### Benefits of using Empty Global Actors 1. It separates the logic from how it is run. A win! 2. They allow us to isolate functions in legacy code. We know you didn’t mean to have file access in your ViewController, but now you have a workaround until you can make a more proper fix. #### Aspect oriented programming? Astute observers have been noting that property wrappers in Swift allow us to do things described in Aspect Oriented Programming. Splitting out functionality into a specific Actor is a valid way to keep different concerns separate in our code. In my work I commonly push back on any solutions that introduce more global variables into existence. But this provides enough benefits to justify it. ### What do you think? Would this work for code you’re working with? What are some other use cases for Empty Global Actors?
jaimzuber.com
December 13, 2024 at 4:03 AM
Avoid Massive Actors with Empty Global Actors
The most common way to think about actors is similar to structs and classes. They are a type with properties or methods defined. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } } This is fine. But this can lead to issues as the codebase grows and logic changes. This article will show a case where an actor with no properties or methods defined (an Empty Global Actor) is a valid option. This can help us remove Massive Actors from our code. ## Background In my work transitioning apps to Swift Concurrency I’ve wanted to use functionality similar to MainActor, but with a custom actor. @CustomActor class SomeClass {} or class SomeIsolatedType { @CustomActor func doWorkOnOtherActor() } This has led me to create Global Actors with no custom functionality. This isn’t how most of us are thinking about actors, but it allows us to do some powerful things. 1. Avoid dumping too much logic into an Actor. The removes the threat of Massive Actors. And leaves us more options as the codebase evolves. 2. Separate the logic in our code from how it is run. This is a powerful technique I’ve used for years to allow code I work with to scale. Let’s talk about an example of where we could use an empty Global Actor. ## Use Case - Restrict Access to File System File access is a classic example of code that is not thread safe. The runtime will gladly modify the same file from multiple threads. This can lead hard to reproduce bugs. Actors in Swift Concurrency provide a way to enforce safe file system access at compile time. ### Possible Approach 1 - add methods to the FileSystemActor One approach for solving this with Swift Concurrency is to add the functionality to an actor. This matches how most of us think about creating actors. And how Apple shows actors being used in their documentation. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } } This will work ok for basic functionality. But has the downside of forcing all file system functionality in to exist in the same type. Even methods that are unrelated and should be broken out into new types. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } func unrelatedFileWrite() { // ... } func thisShouldntBeInTheSameType() { // ... } } #### Downside - Massive Actors **This can lead us to the Massive Actor problem.** ### Possible Approach 2 - bring in the extensions A tempting alternative is to break up large types by using extensions extension FileSystemAccess { func unrelatedFileWrite() { // ... } func thisShouldntBeInTheSameType() { // ... } } **This doesn’t solve anything.** It may split up the functionality into new source files. But the types are still bigger than needed. And the approach has the same downsides as the Massive Actor. Devs do this hoping smaller files make code more readable. But usually it makes things more confusing because you have to look to a new file to understand the behavior the type is responsible for. Neither of these are good solutions for complex functionality. But may work ok for simple use cases. ## Solution - use an Global Actor This allows you to annotate classes, properties and methods with a custom actor. This requires a Global Actor to be defined. @globalActor actor FileSystemActor { static let shared = FileSystemActor() } This allows us to annotate our classes and structs with a custom actor @FileSystemActor class SomeClass { let fileSystem = FileSystemAccess() func readFromFile(urlString: String) async { await fileSystem.readFromFile(urlString: urlString) } } This also works for properties class SomeClass { @FileSystemActor let fileSystem = FileSystemAccess() } and methods class SomeClass { @FileSystemActor func accessSomething() { } } For our use case, the actor doesn’t need any functionality defined at all. It’s an Empty Global Actor. ### Benefits of using Empty Global Actors 1. It separates the logic from how it is run. A win! 2. They allow us to isolate functions in legacy code. We know you didn’t mean to have file access in your ViewController, but now you have a workaround until you can make a more proper fix. #### Aspect oriented programming? Astute observers have been noting that property wrappers in Swift allow us to do things described in Aspect Oriented Programming. Splitting out functionality into a specific Actor is a valid way to keep different concerns separate in our code. In my work I commonly push back on any solutions that introduce more global variables into existence. But this provides enough benefits to justify it. ### What do you think? Would this work for code you’re working with? What are some other use cases for Empty Global Actors?
jaimzuber.com
December 6, 2024 at 3:51 AM
Avoid Massive Actors with Empty Global Actors
The most common way to think about actors is similar to structs and classes. They are a type with properties or methods defined. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } } This is fine. But this can lead to issues as the codebase grows and logic changes. This article will show a case where an actor with no properties or methods defined (an Empty Global Actor) is a valid option. This can help us remove Massive Actors from our code. ## Background In my work transitioning apps to Swift Concurrency I’ve wanted to use functionality similar to MainActor, but with a custom actor. @CustomActor class SomeClass {} or class SomeIsolatedType { @CustomActor func doWorkOnOtherActor() } This has led me to create Global Actors with no custom functionality. This isn’t how most of us are thinking about actors, but it allows us to do some powerful things. 1. Avoid dumping too much logic into an Actor. The removes the threat of Massive Actors. And leaves us more options as the codebase evolves. 2. Separate the logic in our code from how it is run. This is a powerful technique I’ve used for years to allow code I work with to scale. Let’s talk about an example of where we could use an empty Global Actor. ## Use Case - Restrict Access to File System File access is a classic example of code that is not thread safe. The runtime will gladly modify the same file from multiple threads. This can lead hard to reproduce bugs. Actors in Swift Concurrency provide a way to enforce safe file system access at compile time. ### Possible Approach 1 - add methods to the FileSystemActor One approach for solving this with Swift Concurrency is to add the functionality to an actor. This matches how most of us think about creating actors. And how Apple shows actors being used in their documentation. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } } This will work ok for basic functionality. But has the downside of forcing all file system functionality in to exist in the same type. Even methods that are unrelated and should be broken out into new types. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } func unrelatedFileWrite() { // ... } func thisShouldntBeInTheSameType() { // ... } } #### Downside - Massive Actors **This can lead us to the Massive Actor problem.** ### Possible Approach 2 - bring in the extensions A tempting alternative is to break up large types by using extensions extension FileSystemAccess { func unrelatedFileWrite() { // ... } func thisShouldntBeInTheSameType() { // ... } } **This doesn’t solve anything.** It may split up the functionality into new source files. But the types are still bigger than needed. And the approach has the same downsides as the Massive Actor. Devs do this hoping smaller files make code more readable. But usually it makes things more confusing because you have to look to a new file to understand the behavior the type is responsible for. Neither of these are good solutions for complex functionality. But may work ok for simple use cases. ## Solution - use an Global Actor This allows you to annotate classes, properties and methods with a custom actor. This requires a Global Actor to be defined. @globalActor actor FileSystemActor { static let shared = FileSystemActor() } This allows us to annotate our classes and structs with a custom actor @FileSystemActor class SomeClass { let fileSystem = FileSystemAccess() func readFromFile(urlString: String) async { await fileSystem.readFromFile(urlString: urlString) } } This also works for properties class SomeClass { @FileSystemActor let fileSystem = FileSystemAccess() } and methods class SomeClass { @FileSystemActor func accessSomething() { } } For our use case, the actor doesn’t need any functionality defined at all. It’s an Empty Global Actor. ### Benefits of using Empty Global Actors 1. It separates the logic from how it is run. A win! 2. They allow us to isolate functions in legacy code. We know you didn’t mean to have file access in your ViewController, but now you have a workaround until you can make a more proper fix. #### Aspect oriented programming? Astute observers have been noting that property wrappers in Swift allow us to do things described in Aspect Oriented Programming. Splitting out functionality into a specific Actor is a valid way to keep different concerns separate in our code. In my work I commonly push back on any solutions that introduce more global variables into existence. But this provides enough benefits to justify it. ### What do you think? Would this work for code you’re working with? What are some other use cases for Empty Global Actors?
jaimzuber.com
November 27, 2024 at 3:52 AM
Avoid Massive Actors with Empty Global Actors
The most common way to think about actors is similar to structs and classes. They are a type with properties or methods defined. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } } This is fine. But this can lead to issues as the codebase grows and logic changes. This article will show a case where an actor with no properties or methods defined (an Empty Global Actor) is a valid option. This can help us remove Massive Actors from our code. ## Background In my work transitioning apps to Swift Concurrency I’ve wanted to use functionality similar to MainActor, but with a custom actor. @CustomActor class SomeClass {} or class SomeIsolatedType { @CustomActor func doWorkOnOtherActor() } This has led me to create Global Actors with no custom functionality. This isn’t how most of us are thinking about actors, but it allows us to do some powerful things. 1. Avoid dumping too much logic into an Actor. The removes the threat of Massive Actors. And leaves us more options as the codebase evolves. 2. Separate the logic in our code from how it is run. This is a powerful technique I’ve used for years to allow code I work with to scale. Let’s talk about an example of where we could use an empty Global Actor. ## Use Case - Restrict Access to File System File access is a classic example of code that is not thread safe. The runtime will gladly modify the same file from multiple threads. This can lead hard to reproduce bugs. Actors in Swift Concurrency provide a way to enforce safe file system access at compile time. ### Possible Approach 1 - add methods to the FileSystemActor One approach for solving this with Swift Concurrency is to add the functionality to an actor. This matches how most of us think about creating actors. And how Apple shows actors being used in their documentation. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } } This will work ok for basic functionality. But has the downside of forcing all file system functionality in to exist in the same type. Even methods that are unrelated and should be broken out into new types. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } func unrelatedFileWrite() { // ... } func thisShouldntBeInTheSameType() { // ... } } #### Downside - Massive Actors **This can lead us to the Massive Actor problem.** ### Possible Approach 2 - bring in the extensions A tempting alternative is to break up large types by using extensions extension FileSystemAccess { func unrelatedFileWrite() { // ... } func thisShouldntBeInTheSameType() { // ... } } **This doesn’t solve anything.** It may split up the functionality into new source files. But the types are still bigger than needed. And the approach has the same downsides as the Massive Actor. Devs do this hoping smaller files make code more readable. But usually it makes things more confusing because you have to look to a new file to understand the behavior the type is responsible for. Neither of these are good solutions for complex functionality. But may work ok for simple use cases. ## Solution - use an Global Actor This allows you to annotate classes, properties and methods with a custom actor. This requires a Global Actor to be defined. @globalActor actor FileSystemActor { static let shared = FileSystemActor() } This allows us to annotate our classes and structs with a custom actor @FileSystemActor class SomeClass { let fileSystem = FileSystemAccess() func readFromFile(urlString: String) async { await fileSystem.readFromFile(urlString: urlString) } } This also works for properties class SomeClass { @FileSystemActor let fileSystem = FileSystemAccess() } and methods class SomeClass { @FileSystemActor func accessSomething() { } } For our use case, the actor doesn’t need any functionality defined at all. It’s an Empty Global Actor. ### Benefits of using Empty Global Actors 1. It separates the logic from how it is run. A win! 2. They allow us to isolate functions in legacy code. We know you didn’t mean to have file access in your ViewController, but now you have a workaround until you can make a more proper fix. #### Aspect oriented programming? Astute observers have been noting that property wrappers in Swift allow us to do things described in Aspect Oriented Programming. Splitting out functionality into a specific Actor is a valid way to keep different concerns separate in our code. In my work I commonly push back on any solutions that introduce more global variables into existence. But this provides enough benefits to justify it. ### What do you think? Would this work for code you’re working with? What are some other use cases for Empty Global Actors?
jaimzuber.com
November 20, 2024 at 3:54 AM
Avoid Massive Actors with Empty Global Actors
The most common way to think about actors is similar to structs and classes. They are a type with properties or methods defined. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } } This is fine. But this can lead to issues as the codebase grows and logic changes. This article will show a case where an actor with no properties or methods defined (an Empty Global Actor) is a valid option. This can help us remove Massive Actors from our code. ## Background In my work transitioning apps to Swift Concurrency I’ve wanted to use functionality similar to MainActor, but with a custom actor. @CustomActor class SomeClass {} or class SomeIsolatedType { @CustomActor func doWorkOnOtherActor() } This has led me to create Global Actors with no custom functionality. This isn’t how most of us are thinking about actors, but it allows us to do some powerful things. 1. Avoid dumping too much logic into an Actor. The removes the threat of Massive Actors. And leaves us more options as the codebase evolves. 2. Separate the logic in our code from how it is run. This is a powerful technique I’ve used for years to allow code I work with to scale. Let’s talk about an example of where we could use an empty Global Actor. ## Use Case - Restrict Access to File System File access is a classic example of code that is not thread safe. The runtime will gladly modify the same file from multiple threads. This can lead hard to reproduce bugs. Actors in Swift Concurrency provide a way to enforce safe file system access at compile time. ### Possible Approach 1 - add methods to the FileSystemActor One approach for solving this with Swift Concurrency is to add the functionality to an actor. This matches how most of us think about creating actors. And how Apple shows actors being used in their documentation. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } } This will work ok for basic functionality. But has the downside of forcing all file system functionality in to exist in the same type. Even methods that are unrelated and should be broken out into new types. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } func unrelatedFileWrite() { // ... } func thisShouldntBeInTheSameType() { // ... } } #### Downside - Massive Actors **This can lead us to the Massive Actor problem.** ### Possible Approach 2 - bring in the extensions A tempting alternative is to break up large types by using extensions extension FileSystemAccess { func unrelatedFileWrite() { // ... } func thisShouldntBeInTheSameType() { // ... } } **This doesn’t solve anything.** It may split up the functionality into new source files. But the types are still bigger than needed. And the approach has the same downsides as the Massive Actor. Devs do this hoping smaller files make code more readable. But usually it makes things more confusing because you have to look to a new file to understand the behavior the type is responsible for. Neither of these are good solutions for complex functionality. But may work ok for simple use cases. ## Solution - use an Global Actor This allows you to annotate classes, properties and methods with a custom actor. This requires a Global Actor to be defined. @globalActor actor FileSystemActor { static let shared = FileSystemActor() } This allows us to annotate our classes and structs with a custom actor @FileSystemActor class SomeClass { let fileSystem = FileSystemAccess() func readFromFile(urlString: String) async { await fileSystem.readFromFile(urlString: urlString) } } This also works for properties class SomeClass { @FileSystemActor let fileSystem = FileSystemAccess() } and methods class SomeClass { @FileSystemActor func accessSomething() { } } For our use case, the actor doesn’t need any functionality defined at all. It’s an Empty Global Actor. ### Benefits of using Empty Global Actors 1. It separates the logic from how it is run. A win! 2. They allow us to isolate functions in legacy code. We know you didn’t mean to have file access in your ViewController, but now you have a workaround until you can make a more proper fix. #### Aspect oriented programming? Astute observers have been noting that property wrappers in Swift allow us to do things described in Aspect Oriented Programming. Splitting out functionality into a specific Actor is a valid way to keep different concerns separate in our code. In my work I commonly push back on any solutions that introduce more global variables into existence. But this provides enough benefits to justify it. ### What do you think? Would this work for code you’re working with? What are some other use cases for Empty Global Actors?
jaimzuber.com
November 12, 2024 at 3:50 AM
Avoid Massive Actors with Empty Global Actors
The most common way to think about actors is similar to structs and classes. They are a type with properties or methods defined. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } } This is fine. But this can lead to issues as the codebase grows and logic changes. This article will show a case where an actor with no properties or methods defined (an Empty Global Actor) is a valid option. This can help us remove Massive Actors from our code. ## Background In my work transitioning apps to Swift Concurrency I’ve wanted to use functionality similar to MainActor, but with a custom actor. @CustomActor class SomeClass {} or class SomeIsolatedType { @CustomActor func doWorkOnOtherActor() } This has led me to create Global Actors with no custom functionality. This isn’t how most of us are thinking about actors, but it allows us to do some powerful things. 1. Avoid dumping too much logic into an Actor. The removes the threat of Massive Actors. And leaves us more options as the codebase evolves. 2. Separate the logic in our code from how it is run. This is a powerful technique I’ve used for years to allow code I work with to scale. Let’s talk about an example of where we could use an empty Global Actor. ## Use Case - Restrict Access to File System File access is a classic example of code that is not thread safe. The runtime will gladly modify the same file from multiple threads. This can lead hard to reproduce bugs. Actors in Swift Concurrency provide a way to enforce safe file system access at compile time. ### Possible Approach 1 - add methods to the FileSystemActor One approach for solving this with Swift Concurrency is to add the functionality to an actor. This matches how most of us think about creating actors. And how Apple shows actors being used in their documentation. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } } This will work ok for basic functionality. But has the downside of forcing all file system functionality in to exist in the same type. Even methods that are unrelated and should be broken out into new types. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } func unrelatedFileWrite() { // ... } func thisShouldntBeInTheSameType() { // ... } } #### Downside - Massive Actors **This can lead us to the Massive Actor problem.** ### Possible Approach 2 - bring in the extensions A tempting alternative is to break up large types by using extensions extension FileSystemAccess { func unrelatedFileWrite() { // ... } func thisShouldntBeInTheSameType() { // ... } } **This doesn’t solve anything.** It may split up the functionality into new source files. But the types are still bigger than needed. And the approach has the same downsides as the Massive Actor. Devs do this hoping smaller files make code more readable. But usually it makes things more confusing because you have to look to a new file to understand the behavior the type is responsible for. Neither of these are good solutions for complex functionality. But may work ok for simple use cases. ## Solution - use an Global Actor This allows you to annotate classes, properties and methods with a custom actor. This requires a Global Actor to be defined. @globalActor actor FileSystemActor { static let shared = FileSystemActor() } This allows us to annotate our classes and structs with a custom actor @FileSystemActor class SomeClass { let fileSystem = FileSystemAccess() func readFromFile(urlString: String) async { await fileSystem.readFromFile(urlString: urlString) } } This also works for properties class SomeClass { @FileSystemActor let fileSystem = FileSystemAccess() } and methods class SomeClass { @FileSystemActor func accessSomething() { } } For our use case, the actor doesn’t need any functionality defined at all. It’s an Empty Global Actor. ### Benefits of using Empty Global Actors 1. It separates the logic from how it is run. A win! 2. They allow us to isolate functions in legacy code. We know you didn’t mean to have file access in your ViewController, but now you have a workaround until you can make a more proper fix. #### Aspect oriented programming? Astute observers have been noting that property wrappers in Swift allow us to do things described in Aspect Oriented Programming. Splitting out functionality into a specific Actor is a valid way to keep different concerns separate in our code. In my work I commonly push back on any solutions that introduce more global variables into existence. But this provides enough benefits to justify it. ### What do you think? Would this work for code you’re working with? What are some other use cases for Empty Global Actors?
jaimzuber.com
November 4, 2024 at 3:50 AM
Avoid Massive Actors with Empty Global Actors
The most common way to think about actors is similar to structs and classes. They are a type with properties or methods defined. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } } This is fine. But this can lead to issues as the codebase grows and logic changes. This article will show a case where an actor with no properties or methods defined (an Empty Global Actor) is a valid option. This can help us remove Massive Actors from our code. ## Background In my work transitioning apps to Swift Concurrency I’ve wanted to use functionality similar to MainActor, but with a custom actor. @CustomActor class SomeClass {} or class SomeIsolatedType { @CustomActor func doWorkOnOtherActor() } This has led me to create Global Actors with no custom functionality. This isn’t how most of us are thinking about actors, but it allows us to do some powerful things. 1. Avoid dumping too much logic into an Actor. The removes the threat of Massive Actors. And leaves us more options as the codebase evolves. 2. Separate the logic in our code from how it is run. This is a powerful technique I’ve used for years to allow code I work with to scale. Let’s talk about an example of where we could use an empty Global Actor. ## Use Case - Restrict Access to File System File access is a classic example of code that is not thread safe. The runtime will gladly modify the same file from multiple threads. This can lead hard to reproduce bugs. Actors in Swift Concurrency provide a way to enforce safe file system access at compile time. ### Possible Approach 1 - add methods to the FileSystemActor One approach for solving this with Swift Concurrency is to add the functionality to an actor. This matches how most of us think about creating actors. And how Apple shows actors being used in their documentation. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } } This will work ok for basic functionality. But has the downside of forcing all file system functionality in to exist in the same type. Even methods that are unrelated and should be broken out into new types. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } func unrelatedFileWrite() { // ... } func thisShouldntBeInTheSameType() { // ... } } #### Downside - Massive Actors **This can lead us to the Massive Actor problem.** ### Possible Approach 2 - bring in the extensions A tempting alternative is to break up large types by using extensions extension FileSystemAccess { func unrelatedFileWrite() { // ... } func thisShouldntBeInTheSameType() { // ... } } **This doesn’t solve anything.** It may split up the functionality into new source files. But the types are still bigger than needed. And the approach has the same downsides as the Massive Actor. Devs do this hoping smaller files make code more readable. But usually it makes things more confusing because you have to look to a new file to understand the behavior the type is responsible for. Neither of these are good solutions for complex functionality. But may work ok for simple use cases. ## Solution - use an Global Actor This allows you to annotate classes, properties and methods with a custom actor. This requires a Global Actor to be defined. @globalActor actor FileSystemActor { static let shared = FileSystemActor() } This allows us to annotate our classes and structs with a custom actor @FileSystemActor class SomeClass { let fileSystem = FileSystemAccess() func readFromFile(urlString: String) async { await fileSystem.readFromFile(urlString: urlString) } } This also works for properties class SomeClass { @FileSystemActor let fileSystem = FileSystemAccess() } and methods class SomeClass { @FileSystemActor func accessSomething() { } } For our use case, the actor doesn’t need any functionality defined at all. It’s an Empty Global Actor. ### Benefits of using Empty Global Actors 1. It separates the logic from how it is run. A win! 2. They allow us to isolate functions in legacy code. We know you didn’t mean to have file access in your ViewController, but now you have a workaround until you can make a more proper fix. #### Aspect oriented programming? Astute observers have been noting that property wrappers in Swift allow us to do things described in Aspect Oriented Programming. Splitting out functionality into a specific Actor is a valid way to keep different concerns separate in our code. In my work I commonly push back on any solutions that introduce more global variables into existence. But this provides enough benefits to justify it. ### What do you think? Would this work for code you’re working with? What are some other use cases for Empty Global Actors?
jaimzuber.com
October 2, 2024 at 2:00 PM
Avoid Massive Actors with Empty Global Actors
The most common way to think about actors is similar to structs and classes. They are a type with properties or methods defined. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } } This is fine. But this can lead to issues as the codebase grows and logic changes. This article will show a case where an actor with no properties or methods defined (an Empty Global Actor) is a valid option. This can help us remove Massive Actors from our code. ## Background In my work transitioning apps to Swift Concurrency I’ve wanted to use functionality similar to MainActor, but with a custom actor. @CustomActor class SomeClass {} or class SomeIsolatedType { @CustomActor func doWorkOnOtherActor() } This has led me to create Global Actors with no custom functionality. This isn’t how most of us are thinking about actors, but it allows us to do some powerful things. 1. Avoid dumping too much logic into an Actor. The removes the threat of Massive Actors. And leaves us more options as the codebase evolves. 2. Separate the logic in our code from how it is run. This is a powerful technique I’ve used for years to allow code I work with to scale. Let’s talk about an example of where we could use an empty Global Actor. ## Use Case - Restrict Access to File System File access is a classic example of code that is not thread safe. The runtime will gladly modify the same file from multiple threads. This can lead hard to reproduce bugs. Actors in Swift Concurrency provide a way to enforce safe file system access at compile time. ### Possible Approach 1 - add methods to the FileSystemActor One approach for solving this with Swift Concurrency is to add the functionality to an actor. This matches how most of us think about creating actors. And how Apple shows actors being used in their documentation. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } } This will work ok for basic functionality. But has the downside of forcing all file system functionality in to exist in the same type. Even methods that are unrelated and should be broken out into new types. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } func unrelatedFileWrite() { // ... } func thisShouldntBeInTheSameType() { // ... } } #### Downside - Massive Actors **This can lead us to the Massive Actor problem.** ### Possible Approach 2 - bring in the extensions A tempting alternative is to break up large types by using extensions extension FileSystemAccess { func unrelatedFileWrite() { // ... } func thisShouldntBeInTheSameType() { // ... } } **This doesn’t solve anything.** It may split up the functionality into new source files. But the types are still bigger than needed. And the approach has the same downsides as the Massive Actor. Devs do this hoping smaller files make code more readable. But usually it makes things more confusing because you have to look to a new file to understand the behavior the type is responsible for. Neither of these are good solutions for complex functionality. But may work ok for simple use cases. ## Solution - use an Global Actor This allows you to annotate classes, properties and methods with a custom actor. This requires a Global Actor to be defined. @globalActor actor FileSystemActor { static let shared = FileSystemActor() } This allows us to annotate our classes and structs with a custom actor @FileSystemActor class SomeClass { let fileSystem = FileSystemAccess() func readFromFile(urlString: String) async { await fileSystem.readFromFile(urlString: urlString) } } This also works for properties class SomeClass { @FileSystemActor let fileSystem = FileSystemAccess() } and methods class SomeClass { @FileSystemActor func accessSomething() { } } For our use case, the actor doesn’t need any functionality defined at all. It’s an Empty Global Actor. ### Benefits of using Empty Global Actors 1. It separates the logic from how it is run. A win! 2. They allow us to isolate functions in legacy code. We know you didn’t mean to have file access in your ViewController, but now you have a workaround until you can make a more proper fix. #### Aspect oriented programming? Astute observers have been noting that property wrappers in Swift allow us to do things described in Aspect Oriented Programming. Splitting out functionality into a specific Actor is a valid way to keep different concerns separate in our code. In my work I commonly push back on any solutions that introduce more global variables into existence. But this provides enough benefits to justify it. ### What do you think? Would this work for code you’re working with? What are some other use cases for Empty Global Actors?
jaimzuber.com
October 2, 2024 at 2:00 PM
Avoid Massive Actors with Empty Global Actors
The most common way to think about actors is similar to structs and classes. They are a type with properties or methods defined. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } } This is fine. But this can lead to issues as the codebase grows and logic changes. This article will show a case where an actor with no properties or methods defined (an Empty Global Actor) is a valid option. This can help us remove Massive Actors from our code. ## Background In my work transitioning apps to Swift Concurrency I’ve wanted to use functionality similar to MainActor, but with a custom actor. @CustomActor class SomeClass {} or class SomeIsolatedType { @CustomActor func doWorkOnOtherActor() } This has led me to create Global Actors with no custom functionality. This isn’t how most of us are thinking about actors, but it allows us to do some powerful things. 1. Avoid dumping too much logic into an Actor. The removes the threat of Massive Actors. And leaves us more options as the codebase evolves. 2. Separate the logic in our code from how it is run. This is a powerful technique I’ve used for years to allow code I work with to scale. Let’s talk about an example of where we could use an empty Global Actor. ## Use Case - Restrict Access to File System File access is a classic example of code that is not thread safe. The runtime will gladly modify the same file from multiple threads. This can lead hard to reproduce bugs. Actors in Swift Concurrency provide a way to enforce safe file system access at compile time. ### Possible Approach 1 - add methods to the FileSystemActor One approach for solving this with Swift Concurrency is to add the functionality to an actor. This matches how most of us think about creating actors. And how Apple shows actors being used in their documentation. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } } This will work ok for basic functionality. But has the downside of forcing all file system functionality in to exist in the same type. Even methods that are unrelated and should be broken out into new types. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } func unrelatedFileWrite() { // ... } func thisShouldntBeInTheSameType() { // ... } } #### Downside - Massive Actors **This can lead us to the Massive Actor problem.** ### Possible Approach 2 - bring in the extensions A tempting alternative is to break up large types by using extensions extension FileSystemAccess { func unrelatedFileWrite() { // ... } func thisShouldntBeInTheSameType() { // ... } } **This doesn’t solve anything.** It may split up the functionality into new source files. But the types are still bigger than needed. And the approach has the same downsides as the Massive Actor. Devs do this hoping smaller files make code more readable. But usually it makes things more confusing because you have to look to a new file to understand the behavior the type is responsible for. Neither of these are good solutions for complex functionality. But may work ok for simple use cases. ## Solution - use an Global Actor This allows you to annotate classes, properties and methods with a custom actor. This requires a Global Actor to be defined. @globalActor actor FileSystemActor { static let shared = FileSystemActor() } This allows us to annotate our classes and structs with a custom actor @FileSystemActor class SomeClass { let fileSystem = FileSystemAccess() func readFromFile(urlString: String) async { await fileSystem.readFromFile(urlString: urlString) } } This also works for properties class SomeClass { @FileSystemActor let fileSystem = FileSystemAccess() } and methods class SomeClass { @FileSystemActor func accessSomething() { } } For our use case, the actor doesn’t need any functionality defined at all. It’s an Empty Global Actor. ### Benefits of using Empty Global Actors 1. It separates the logic from how it is run. A win! 2. They allow us to isolate functions in legacy code. We know you didn’t mean to have file access in your ViewController, but now you have a workaround until you can make a more proper fix. #### Aspect oriented programming? Astute observers have been noting that property wrappers in Swift allow us to do things described in Aspect Oriented Programming. Splitting out functionality into a specific Actor is a valid way to keep different concerns separate in our code. In my work I commonly push back on any solutions that introduce more global variables into existence. But this provides enough benefits to justify it. ### What do you think? Would this work for code you’re working with? What are some other use cases for Empty Global Actors?
jaimzuber.com
October 2, 2024 at 2:00 PM
Avoid Massive Actors with Empty Global Actors
The most common way to think about actors is similar to structs and classes. They are a type with properties or methods defined. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } } This is fine. But this can lead to issues as the codebase grows and logic changes. This article will show a case where an actor with no properties or methods defined (an Empty Global Actor) is a valid option. This can help us remove Massive Actors from our code. ## Background In my work transitioning apps to Swift Concurrency I’ve wanted to use functionality similar to MainActor, but with a custom actor. @CustomActor class SomeClass {} or class SomeIsolatedType { @CustomActor func doWorkOnOtherActor() } This has led me to create Global Actors with no custom functionality. This isn’t how most of us are thinking about actors, but it allows us to do some powerful things. 1. Avoid dumping too much logic into an Actor. The removes the threat of Massive Actors. And leaves us more options as the codebase evolves. 2. Separate the logic in our code from how it is run. This is a powerful technique I’ve used for years to allow code I work with to scale. Let’s talk about an example of where we could use an empty Global Actor. ## Use Case - Restrict Access to File System File access is a classic example of code that is not thread safe. The runtime will gladly modify the same file from multiple threads. This can lead hard to reproduce bugs. Actors in Swift Concurrency provide a way to enforce safe file system access at compile time. ### Possible Approach 1 - add methods to the FileSystemActor One approach for solving this with Swift Concurrency is to add the functionality to an actor. This matches how most of us think about creating actors. And how Apple shows actors being used in their documentation. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } } This will work ok for basic functionality. But has the downside of forcing all file system functionality in to exist in the same type. Even methods that are unrelated and should be broken out into new types. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } func unrelatedFileWrite() { // ... } func thisShouldntBeInTheSameType() { // ... } } #### Downside - Massive Actors **This can lead us to the Massive Actor problem.** ### Possible Approach 2 - bring in the extensions A tempting alternative is to break up large types by using extensions extension FileSystemAccess { func unrelatedFileWrite() { // ... } func thisShouldntBeInTheSameType() { // ... } } **This doesn’t solve anything.** It may split up the functionality into new source files. But the types are still bigger than needed. And the approach has the same downsides as the Massive Actor. Devs do this hoping smaller files make code more readable. But usually it makes things more confusing because you have to look to a new file to understand the behavior the type is responsible for. Neither of these are good solutions for complex functionality. But may work ok for simple use cases. ## Solution - use an Global Actor This allows you to annotate classes, properties and methods with a custom actor. This requires a Global Actor to be defined. @globalActor actor FileSystemActor { static let shared = FileSystemActor() } This allows us to annotate our classes and structs with a custom actor @FileSystemActor class SomeClass { let fileSystem = FileSystemAccess() func readFromFile(urlString: String) async { await fileSystem.readFromFile(urlString: urlString) } } This also works for properties class SomeClass { @FileSystemActor let fileSystem = FileSystemAccess() } and methods class SomeClass { @FileSystemActor func accessSomething() { } } For our use case, the actor doesn’t need any functionality defined at all. It’s an Empty Global Actor. ### Benefits of using Empty Global Actors 1. It separates the logic from how it is run. A win! 2. They allow us to isolate functions in legacy code. We know you didn’t mean to have file access in your ViewController, but now you have a workaround until you can make a more proper fix. #### Aspect oriented programming? Astute observers have been noting that property wrappers in Swift allow us to do things described in Aspect Oriented Programming. Splitting out functionality into a specific Actor is a valid way to keep different concerns separate in our code. In my work I commonly push back on any solutions that introduce more global variables into existence. But this provides enough benefits to justify it. ### What do you think? Would this work for code you’re working with? What are some other use cases for Empty Global Actors?
jaimzuber.com
October 2, 2024 at 2:00 PM
Empty Global Actors
The most common way to think about actors is similar to structs and classes. They are a type with properties or methods defined. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } } This is fine. But this can lead to issues as the codebase grows and logic changes. This article will show a case where an actor with no properties or methods defined (an Empty Global Actor) is a valid option. This can help us remove Massive Actors from our code. ## Background In my work transitioning apps to Swift Concurrency I’ve wanted to use functionality similar to MainActor, but with a custom actor. @CustomActor class SomeClass {} or class SomeIsolatedType { @CustomActor func doWorkOnOtherActor() } This has led me to create Global Actors with no custom functionality. This isn’t how most of us are thinking about actors, but it allows us to do some powerful things. 1. Avoid dumping too much logic into an Actor. The removes the threat of Massive Actors. And leaves us more options as the codebase evolves. 2. Separate the logic in our code from how it is run. This is a powerful technique I’ve used for years to allow code I work with to scale. Let’s talk about an example of where we could use an empty Global Actor. ## Use Case - Restrict Access to File System File access is a classic example of code that is not thread safe. The runtime will gladly modify the same file from multiple threads. This can lead hard to reproduce bugs. Actors in Swift Concurrency provide a way to enforce safe file system access at compile time. ### Possible Approach 1 - add methods to the FileSystemActor One approach for solving this with Swift Concurrency is to add the functionality to an actor. This matches how most of us think about creating actors. And how Apple shows actors being used in their documentation. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } } This will work ok for basic functionality. But has the downside of forcing all file system functionality in to exist in the same type. Even methods that are unrelated and should be broken out into new types. actor FileSystemAccess { func readFromFile(urlString: String) { FileManager.default.contents(atPath: urlString) } func unrelatedFileWrite() { // ... } func thisShouldntBeInTheSameType() { // ... } } #### Downside - Massive Actors **This can lead us to the Massive Actor problem.** ### Possible Approach 2 - bring in the extensions A tempting alternative is to break up large types by using extensions extension FileSystemAccess { func unrelatedFileWrite() { // ... } func thisShouldntBeInTheSameType() { // ... } } **This doesn’t solve anything.** It may split up the functionality into new source files. But the types are still bigger than needed. And the approach has the same downsides as the Massive Actor. Devs do this hoping smaller files make code more readable. But usually it makes things more confusing because you have to look to a new file to understand the behavior the type is responsible for. Neither of these are good solutions for complex functionality. But may work ok for simple use cases. ## Solution - use an Global Actor This allows you to annotate classes, properties and methods with a custom actor. This requires a Global Actor to be defined. @globalActor actor FileSystemActor { static let shared = FileSystemActor() } This allows us to annotate our classes and structs with a custom actor @FileSystemActor class SomeClass { let fileSystem = FileSystemAccess() func readFromFile(urlString: String) async { await fileSystem.readFromFile(urlString: urlString) } } This also works for properties class SomeClass { @FileSystemActor let fileSystem = FileSystemAccess() } and methods class SomeClass { @FileSystemActor func accessSomething() { } } For our use case, the actor doesn’t need any functionality defined at all. It’s an Empty Global Actor. ### Benefits of using Empty Global Actors 1. It separates the logic from how it is run. A win! 2. They allow us to isolate functions in legacy code. We know you didn’t mean to have file access in your ViewController, but now you have a workaround until you can make a more proper fix. #### Aspect oriented programming? Astute observers have been noting that property wrappers in Swift allow us to do things described in Aspect Oriented Programming. Splitting out functionality into a specific Actor is a valid way to keep different concerns separate in our code. In my work I commonly push back on any solutions that introduce more global variables into existence. But this provides enough benefits to justify it. ### What do you think? Would this work for code you’re working with? What are some other use cases for Empty Global Actors?
jaimzuber.com
October 2, 2024 at 2:00 PM
Google chrome最新バージョンを一部利用者に対して配信|5件の脆弱性を解消

2025年5月21日、Googleは早期安定版として「Chrome 137」をリリースし、複数のセキュリティ脆弱性を修正しました。この記事ではその概要について紹介します。 Chrome 137で修正された主要な脆弱性 新しいバージョンのChromeには、全部で8件の脆弱性が修正されています。以下は、その中でも公にされている5つの脆弱性について紹介します。 今回のセキュリティアップデートは、早期安定版(Early…
Google chrome最新バージョンを一部利用者に対して配信|5件の脆弱性を解消
2025年5月21日、Googleは早期安定版として「Chrome 137」をリリースし、複数のセキュリティ脆弱性を修正しました。この記事ではその概要について紹介します。 Chrome 137で修正された主要な脆弱性 新しいバージョンのChromeには、全部で8件の脆弱性が修正されています。以下は、その中でも公にされている5つの脆弱性について紹介します。 今回のセキュリティアップデートは、早期安定版(Early Stable)として正式な安定版公開の約1週間前に、一部のユーザー向けに提供しているものになります。 CVE番号 概要 深刻度 CVE-2025-5063 Firefo合成処理における解放後使用 高 CVE-2025-5064 バックグラウンドフェッチにおける不適切な実装 中 CVE-2025-5065 FileSystemAccess APIの不適切な実装 中 CVE-2025-5066 Messagesにおける不適切な実装 中 CVE-2025-5067 タブストリップの不適切な実装 低 ▼ Google chromeからのリリース Google chromeの修正内容について セキュリティアップデートは以下のとおりです。 ▼WindowsおよびmacOS:Chrome 137.0.7151.41、137.0.7151.40 Google Chrome セキュリティアップデートの方法とは Google chromeのセキュリティアップデートは通常、パソコンでブラウザを閉じて次に開くまでの間にバックグラウンドで行われます。そのため、特段対応することはありません。 もし、手動でセキュリティアップデートを行いたい場合は以下の手順で行うことができます。 パソコンで Chrome を開きます。 右上のその他アイコン   [ヘルプ]  [Google Chrome について] を選択します。 [再起動] を選択します。 [再起動] オプションが表示されない場合は、最新バージョンです。 なお、開いていたタブやウィンドウは、ブラウザを再起動したときに自動的に表示されます。(ただしシークレット ウィンドウは表示されません)。すぐに再起動しない場合は、[後で] を選択します。その場合、Chrome を次回再起動したときに更新が適用されます。 ▼ 詳細はこちらから🔗Google Chrome を更新する – パソコン – Google Chrome ヘルプ ▼前回の更新はこちらから まとめ Google Chrome 137のリリースにより、複数の重大な脆弱性が修正され、ユーザーのセキュリティが向上しました。常にブラウザを最新の状態に保つことで、安全なインターネットの利用が可能になります。
www.cybernote.click
May 22, 2025 at 1:58 PM
📢 Chromium: CVE-2025-5065 Inappropriate implementation in FileSystemAccess API
https://msrc.microsoft.com/update-guide/vulnerability/CVE-2025-5065
May 29, 2025 at 10:46 PM