Skip to main content
edited body
Source Link
max630
  • 2.6k
  • 1
  • 13
  • 16

Imagine if someone else calls doWork for that same object right after you do. They "steal" the delegate, and they will get both workDone callbacks

basically, this is what you should be fixing first. As far as I understand from the API reference, you cannot uniquely identify requests so cannot freely sunrun several at once, but you can run in parallel requests of different types, because they call different signatures of callback. Make a wrapper like this (I don't know Swift so making up syntax sometimes):

interface Request {
    func GetRequestData();
    func Callback(resultData);
}

class MyAPIWrapper {
  // this has linear cost for operations, if it is an issue a dictionary of something can be used.
  List<Request> requestsInProgress;
  ApiObj apiObj;

  func Initialize() {
    apiObj.delegate = self
  }

  func callAPI(request) {
    if(TryRegisterRequest(request)) {
         apiObj.doWork(request.GetRequestData());
    } else {
         // caller error: another request is already running which would be indistinguihable
    }
  }

  func workDone(result) {
    Request? request = TryFindAndUnregisterRequest(result);
    if(request != nil) {
      request!.Callback(result);
    } else {
      // internal error: unexpected result
    }
  }

  func TryRegisterRequest(Request request) {
     for (Request r in requestsInProgress) {
        if (....) { // chacks if r matches request
            return false;
        }
     }
     requestsInProgress.Add(request);
  }

  func TryFindAndUnregisterRequest(result) {
     for (Request r in requestsInProgress) {
        if (....) { // checks if r matches result
            requestsInProgress.Remove(r);
            return r; // is this how I construct a filled optional?
        }
     }

     // not found
     return nil;
  }
}

This wrapper provides intercface without the quoted issue. Then, you can make a synchronous wrapper over it. Or not.

Imagine if someone else calls doWork for that same object right after you do. They "steal" the delegate, and they will get both workDone callbacks

basically, this is what you should be fixing first. As far as I understand from the API reference, you cannot uniquely identify requests so cannot freely sun several at once, but you can run in parallel requests of different types, because they call different signatures of callback. Make a wrapper like this (I don't know Swift so making up syntax sometimes):

interface Request {
    func GetRequestData();
    func Callback(resultData);
}

class MyAPIWrapper {
  // this has linear cost for operations, if it is an issue a dictionary of something can be used.
  List<Request> requestsInProgress;
  ApiObj apiObj;

  func Initialize() {
    apiObj.delegate = self
  }

  func callAPI(request) {
    if(TryRegisterRequest(request)) {
         apiObj.doWork(request.GetRequestData());
    } else {
         // caller error: another request is already running which would be indistinguihable
    }
  }

  func workDone(result) {
    Request? request = TryFindAndUnregisterRequest(result);
    if(request != nil) {
      request!.Callback(result);
    } else {
      // internal error: unexpected result
    }
  }

  func TryRegisterRequest(Request request) {
     for (Request r in requestsInProgress) {
        if (....) { // chacks if r matches request
            return false;
        }
     }
     requestsInProgress.Add(request);
  }

  func TryFindAndUnregisterRequest(result) {
     for (Request r in requestsInProgress) {
        if (....) { // checks if r matches result
            requestsInProgress.Remove(r);
            return r; // is this how I construct a filled optional?
        }
     }

     // not found
     return nil;
  }
}

This wrapper provides intercface without the quoted issue. Then, you can make a synchronous wrapper over it. Or not.

Imagine if someone else calls doWork for that same object right after you do. They "steal" the delegate, and they will get both workDone callbacks

basically, this is what you should be fixing first. As far as I understand from the API reference, you cannot uniquely identify requests so cannot freely run several at once, but you can run in parallel requests of different types, because they call different signatures of callback. Make a wrapper like this (I don't know Swift so making up syntax sometimes):

interface Request {
    func GetRequestData();
    func Callback(resultData);
}

class MyAPIWrapper {
  // this has linear cost for operations, if it is an issue a dictionary of something can be used.
  List<Request> requestsInProgress;
  ApiObj apiObj;

  func Initialize() {
    apiObj.delegate = self
  }

  func callAPI(request) {
    if(TryRegisterRequest(request)) {
         apiObj.doWork(request.GetRequestData());
    } else {
         // caller error: another request is already running which would be indistinguihable
    }
  }

  func workDone(result) {
    Request? request = TryFindAndUnregisterRequest(result);
    if(request != nil) {
      request!.Callback(result);
    } else {
      // internal error: unexpected result
    }
  }

  func TryRegisterRequest(Request request) {
     for (Request r in requestsInProgress) {
        if (....) { // chacks if r matches request
            return false;
        }
     }
     requestsInProgress.Add(request);
  }

  func TryFindAndUnregisterRequest(result) {
     for (Request r in requestsInProgress) {
        if (....) { // checks if r matches result
            requestsInProgress.Remove(r);
            return r; // is this how I construct a filled optional?
        }
     }

     // not found
     return nil;
  }
}

This wrapper provides intercface without the quoted issue. Then, you can make a synchronous wrapper over it. Or not.

Source Link
max630
  • 2.6k
  • 1
  • 13
  • 16

Imagine if someone else calls doWork for that same object right after you do. They "steal" the delegate, and they will get both workDone callbacks

basically, this is what you should be fixing first. As far as I understand from the API reference, you cannot uniquely identify requests so cannot freely sun several at once, but you can run in parallel requests of different types, because they call different signatures of callback. Make a wrapper like this (I don't know Swift so making up syntax sometimes):

interface Request {
    func GetRequestData();
    func Callback(resultData);
}

class MyAPIWrapper {
  // this has linear cost for operations, if it is an issue a dictionary of something can be used.
  List<Request> requestsInProgress;
  ApiObj apiObj;

  func Initialize() {
    apiObj.delegate = self
  }

  func callAPI(request) {
    if(TryRegisterRequest(request)) {
         apiObj.doWork(request.GetRequestData());
    } else {
         // caller error: another request is already running which would be indistinguihable
    }
  }

  func workDone(result) {
    Request? request = TryFindAndUnregisterRequest(result);
    if(request != nil) {
      request!.Callback(result);
    } else {
      // internal error: unexpected result
    }
  }

  func TryRegisterRequest(Request request) {
     for (Request r in requestsInProgress) {
        if (....) { // chacks if r matches request
            return false;
        }
     }
     requestsInProgress.Add(request);
  }

  func TryFindAndUnregisterRequest(result) {
     for (Request r in requestsInProgress) {
        if (....) { // checks if r matches result
            requestsInProgress.Remove(r);
            return r; // is this how I construct a filled optional?
        }
     }

     // not found
     return nil;
  }
}

This wrapper provides intercface without the quoted issue. Then, you can make a synchronous wrapper over it. Or not.