Skip to content

Instantly share code, notes, and snippets.

@phylliswong
Created June 28, 2019 23:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save phylliswong/e0fc4ebdea6a246ea76b618336c017f7 to your computer and use it in GitHub Desktop.
Save phylliswong/e0fc4ebdea6a246ea76b618336c017f7 to your computer and use it in GitHub Desktop.
public func get<T>(key: String, defaultValue: T) -> Any {
let group = DispatchGroup()
var allocations = [JSON]()
var value = [JSON]()
if (futureAllocations == nil) { return defaultValue }
// This needs to be a blocking operation
let _ = self.futureAllocations?.done { (jsonArray) in
allocations = jsonArray
}
// lines 9-11 MUST be complete BEFORE the rest of this code executes
if !Allocator.allocationsNotEmpty(allocations: allocations) {
return defaultValue
}
let type = getMyType(defaultValue)
guard let _ = type else { return defaultValue }
do {
let alloc = Allocations(allocations: allocations)
let v = try alloc.getValueFromAllocations(key, type, participant)
if let val = v { value = val }
} catch {
LOGGER.log(.error, message: "Unable to retrieve the treatment. Returning the default.")
return defaultValue
}
return value
}
@phylliswong
Copy link
Author

Things I tried that didn't quite work are:

  1. semaphores
  2. DispatchGroups
  3. DispatchQueue.main.async { .code here }
  4. firstly {
    }.then {
    }.ensure........

The problem is that I am "unpacking" the promise and need to wait for it to be done before the rest of the code gets executed.
SMH 🤷🏽‍♀️

@LinnierGames
Copy link

How did u use dispatch groups?

@phylliswong
Copy link
Author

phylliswong commented Jun 29, 2019

public func get<T>(key: String, defaultValue: T) -> Any {
// init dispatch group here
    let group = DispatchGroup()
    var allocations = [JSON]()
    var value = [JSON]()
    
    if (futureAllocations == nil) { return defaultValue }

   // This needs to be a blocking operation
    group.enter()
    let _ = self.futureAllocations?.done { (jsonArray) in
       allocations = jsonArray
       group.leave()
    } 
   
   group.notify(queue: .main) { [weak self] in
    // here things broke down. my code was like.... weak self what????
    // also i assumed i could wrap the code that needed to complete in here, however that didn't work cuz scope
   }
   // these lines of code executed before the group finished its work :(
    // lines 9-11 MUST be complete BEFORE the rest of this code executes
    if !Allocator.allocationsNotEmpty(allocations: allocations) {
        return defaultValue
    }
  
    let type = getMyType(defaultValue)
    guard let _ = type else { return defaultValue }
    do {
      let alloc = Allocations(allocations: allocations)
      let v = try alloc.getValueFromAllocations(key, type, participant)
      if let val = v { value = val }
    } catch {
      LOGGER.log(.error, message: "Unable to retrieve the treatment. Returning the default.")
      return defaultValue
    }
    return value
  }

@phylliswong
Copy link
Author

I was unable to move the following code inside the notify method because it is a closure that expects a Void return.

@phylliswong
Copy link
Author

Got the solution...it was waaaaay easier than I was making it.

public func get<T>(key: String, defaultValue: T) -> Any {
    var value = [JSON]()
    var promisedAllocations = [JSON]()
    
    if (futureAllocations == nil) {
      print("\(String(describing: futureAllocations))")
      return defaultValue
    }

    do {
      let a = try futureAllocations?.wait()
      guard let alloc = a else {
        return defaultValue
      }
      
      promisedAllocations = alloc
      if !Allocator.allocationsNotEmpty(allocations: promisedAllocations) {
        return defaultValue
      }
      
      let type = getMyType(defaultValue)
      guard let _ = type else { return defaultValue }
      do {
        let alloc = Allocations(allocations: promisedAllocations)
        let v = try alloc.getValueFromAllocations(key, type, participant)
        value = [v] as! [JSON]
      } catch {
        LOGGER.log(.error, message: "Unable to retrieve the treatment. Returning the default.")
        return defaultValue
      }
    } catch {
      LOGGER.log(.debug, message: "Error retrieving Allocations")
    }
    return value
  }

@LinnierGames
Copy link

  let a = try futureAllocations?.wait()

Where is futureAllocations defined?

@phylliswong
Copy link
Author

  let a = try futureAllocations?.wait()

Where is futureAllocations defined?

This gets initialized by the Allocator class's fetch method. When the client gets initialized, the value is a promise. Then when the promise is fulfilled ... after .wait() then I can perform the other tasks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment