es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Usando DispatchGroup con API de Streaming?

Actualmente estoy utilizando un DispatchGroup para recibir una notificación cuando se completan dos llamadas a la API, y luego combino ambas respuestas en un solo objeto, que retorno en un bloque de finalización.

Esto funciona para las API de tipo REST, sin embargo, cuando lo utilizo con dos llamadas de tipo streaming, la aplicación se bloquea debido a la frecuente activación / recuento desigual de dispatchGroup.leave.

¿Existe otra forma de lograr mi objetivo o hay algo que pueda hacer para seguir utilizando un DispatchGroup? A continuación, se muestra un ejemplo rápido para mostrar lo que estoy haciendo.

func fetchPets(completion: @escaping (Result<[Pet], Error>) -> Void) {
    let dispatchGroup = DispatchGroup()
    let dogs: [Dog] = []
    let cats: [Cat] = []

    // Realizar la primera llamada de transmisión
    dispatchGroup.enter()
    fetchDogs(completion: () -> Void) {
        // Hacer algo (transformar datos) y añadir perros al array
        dispatchGroup.leave()
    }

    // Realizar la segunda llamada de transmisión
    dispatchGroup.enter()
    fetchCats(completion: () -> Void) {
        // Hacer algo (transformar datos) y añadir gatos al array
        dispatchGroup.leave()
    }

    // Combinar ambas respuestas una vez que se completen amb éxito ambas llamadas
    dispatchGroup.notify(queue: .main) {
        // Hacer algo con los datos
        let pets = Pet(...)
        completion(pets)
    }
}

Espero que esta información sea de ayuda.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Una posible solución es utilizar una cola de despacho serial en lugar de un DispatchGroup. Puedes crear una cola serial y agregar ambas llamadas de transmisión como tareas a ejecutar de forma secuencial. Una vez que ambas tareas hayan sido completadas, puedes combinar las respuestas y devolverlas en el bloque de finalización. Esto garantizará que las tareas se ejecuten de forma secuencial y no haya condiciones de carrera.

    Otra opción es utilizar un DispatchGroup anidado. Puedes crear un DispatchGroup separado para cada llamada de transmisión e ingresar/salir de los grupos según corresponda. Luego, crea un DispatchGroup padre e ingresa a los grupos hijos. Una vez que ambos grupos hijos han sido completados, el grupo padre será notificado y podrás combinar las respuestas y devolverlas en el bloque de finalización. Esto asegurará que ambas llamadas de transmisión se completen antes de que se devuelva la respuesta combinada.

    Finalmente, también podrías considerar el uso de otras herramientas de concurrencia como NSOperationQueue o el framework Combine, que podrían ofrecer un mejor soporte para APIs de transmisión.

Comments are closed.