admin管理员组

文章数量:1402902

I could be going about this entirely wrong. But basically I am practicing by writing a cache object. It caches to memory and to disk.

Given I do not want to deal with writing proper asynchronous methods for writing data to disk I decided to just sort of queue up the disk writes in a low priority thread.

However once the writes are done I would like to update an in memory structure in my actor to let it know (without file IO) that it would be able to find that file written to disk.

I use detached task because I want load() to be able to return before the disk write is done (especially since its a low priority task) and since it does not require any actor state.

However if this actor were MainActor I could get back to main actor with Task { @MainActor in. But what is the equivalent of this when your class is not main actor?

actor Actor {
   var cachedOnDisk: Bool = false
   func load() async {
      // Some async operations that load this

      // Disk persistence is not important I would like async load() to return ASAP
      Task.detached(priority: .background) {
          // I know this is a bottleneck as this method is not ready for swift asynchronous. I am hoping it does not matter as this is a backup cache.
          try data.write(to: url)
          Task { in
            // If this were a main actor actor I could go @MainActor in but it is not
            await cachedOnDisk = true
          }
       }
   }
}

I could be going about this entirely wrong. But basically I am practicing by writing a cache object. It caches to memory and to disk.

Given I do not want to deal with writing proper asynchronous methods for writing data to disk I decided to just sort of queue up the disk writes in a low priority thread.

However once the writes are done I would like to update an in memory structure in my actor to let it know (without file IO) that it would be able to find that file written to disk.

I use detached task because I want load() to be able to return before the disk write is done (especially since its a low priority task) and since it does not require any actor state.

However if this actor were MainActor I could get back to main actor with Task { @MainActor in. But what is the equivalent of this when your class is not main actor?

actor Actor {
   var cachedOnDisk: Bool = false
   func load() async {
      // Some async operations that load this

      // Disk persistence is not important I would like async load() to return ASAP
      Task.detached(priority: .background) {
          // I know this is a bottleneck as this method is not ready for swift asynchronous. I am hoping it does not matter as this is a backup cache.
          try data.write(to: url)
          Task { in
            // If this were a main actor actor I could go @MainActor in but it is not
            await cachedOnDisk = true
          }
       }
   }
}
Share Improve this question asked Mar 20 at 23:01 CalebKCalebK 7539 silver badges19 bronze badges 1
  • 1 Whenever you access cachedOnDisk or any method of Actor, actor will make sure your access will be isolated to actor context ( an await is a potential context switch), remember that in async, await, callee define the context it might want to run in, not the caller – duckSern1108 Commented Mar 21 at 1:47
Add a comment  | 

1 Answer 1

Reset to default 1

An actor already ensures that all modifications to its state are synchronised on the actor's executor. It's just that you cannot do cachedOnDisk = true directly in a detached task (not isolated to the actor). This is more of a design decision than a technical limitation.

You should write a method that wraps cahcedOnDisk = true:

private func setCached(_ flag: Bool) {
    cachedOnDisk = flag
}

Then you can write:

Task.detached(priority: .background) {
    try data.write(to: url)
    await self.setCached(true)
}

Since setCached is called on self. The call will automatically hop back onto self. This is the guarantee that actors provide.

本文标签: swiftHow to create a task on the originating actor from within a detached taskStack Overflow