Consejos de programación para la interfaz verbs (solo Linux)

El desarrollo de aplicaciones que utilizan la interfaz jVerbs verbs es un proceso complejo. Se proporcionan algunos consejos y mejores prácticas para ayudar a los desarrolladores.

Nota: Inicio de cambios para la actualización del servicio 8 fixpack 30La implementación RDMA, que anteriormente estaba obsoleta se elimina de IBM® SDK, Java™ Technology Edition, Version 8.Fin de los cambios para el Service Refresh 8 Fix Pack 30

Creación de un objeto SVM (Stateful Verbs Method)

Las operaciones con estado evitan el impacto en el rendimiento de pasar estructuras complejas a través de la interfaz nativa Java (JNI) para operaciones de datos de vía de acceso rápida como, por ejemplo, postSend() o postReceive(). Puede crear el objeto de método con estado solo una vez pero puede utilizarlo varias veces. Por ejemplo, puede volver a enviar los mismos datos o recibir datos en los mismos almacenamientos intermedios. El objeto SVM asigna almacenamientos intermedios de bytes directos para retener los parámetros que deben pasarse mediante la JNI. Cuando ya no se necesita un objeto SVM debe liberar el objeto SVM mediante el método free() para que el almacenamiento intermedio pueda marcarse para la recogida de basura. Para saber si la última operación ha sido satisfactoria utilice el método IsSuccess().

Compartir colas de finalización

Cuando se comparten colas de finalización entre varios ID de conexión, asegúrese de que la entrada de cola de finalización tenga el tamaño suficiente para todas las operaciones de envío y de recepción. El límite se establece pasando un argumento al crear la cola utilizando el método createCompletionQueue(). Si hay demasiadas entradas de finalización se produce una excepción IOException cuando se alcanza el límite del dispositivo, y se pasan por alto las otras finalizaciones.

El método WorkCompletion.getQueuePairNum() identifica de forma exclusiva el número de par de cola al que pertenece la entrada de finalización de trabajo. Por lo tanto, el evento de finalización de trabajo se puede asignar al ID de conexión correspondiente para continuar con la operación.

Solicitud de notificación

Debe llamar al método CompletionQueue.requestNotifyCQ() para avisar a la hebra de aplicación cuando la cola de finalización espere a una llamada CompletionChannel.getCQEvent(). Si no solicita la notificación mediante el método CompletionQueue.requestNotifyCQ() no se enviará ninguna notificación cuando se reciba un evento de finalización en la cola de finalización. Sin embargo, los eventos de finalización se colocan en la cola de finalización, que se puede sondear utilizando el método pollCQ().

Cuando se reciba una notificación desde un método getCQEvent() debe volver a llamar al método requestNotifyCQ() para el siguiente método getCQEvent(). No puede llamar al método CompletionQueue.requestNotifyCQ() varias veces para poner solicitudes en cola; solo se registra una solicitud de notificación para el siguiente método getCQEvent().

El método CompletionQueue.requestNotifyCQ() acepta un tipo de datos booleanos que determine si es necesaria una notificación en la cola de finalización para los eventos solicitados o para todos los eventos. Si desea marcar un suceso como solicitado, puede establecer el distintivo IBV_SEND_SOLICITED en la solicitud de trabajo.

Creación de pares de cola

Se necesita un par de cola para publicar solicitudes de envío y de recepción. Al crear un nuevo par de cola debe tener en cuenta otros pares de cola activos que existan en el sistema. Elija un tamaño de par de cola que coincida con el número de solicitudes de trabajo publicadas para el envío o la recepción en cualquier momento. Si se excede el límite del dispositivo de un par de cola se producirá una excepción IOException. Aunque puede establecer un tamaño de par de cola cuando se crea el par de cola, el sistema puede elegir un tamaño más adecuado que se base en los pares de cola existentes y los recursos disponibles. Para determinar el tamaño real de un par de cola después de crearlo, utilice el método QueuePair.getQueuePairLimit().

Publicación de almacenamientos intermedios de envío o de recepción

Las operaciones RDMA son asíncronas. La publicación de un almacenamiento intermedio de envío o de recepción no significa que el trabajo realmente se envíe o se reciba. El cliente o el servidor que ha publicado el almacenamiento intermedio de envío o de recepción debe esperar a que la finalización de trabajo determine si la operación de envío o de recepción ha sido correcta. Puede consultar estados de finalización de trabajo mediante el método WorkCompletion.getStatus() para determinar si ha sido correcto o no. También puede utilizar el método WorkCompletion.getOpcode() para comprobar la finalización de operaciones de envío o de recepción. Si el trabajo se ha completado puede volver a utilizar el almacenamiento intermedio de envío o de recepción. Si la operación publicada no se ha completado, al reutilizar el mismo almacenamiento intermedio registrado se puede producir un bloqueo o la corrupción de la memoria.

Los almacenamientos intermedios deben estar en vigor antes de conectarse desde el lado de cliente y antes de aceptarlos en el lado del servidor para evitar que se pierda cualquier transferencia de datos al establecer la conexión. La posición del almacenamiento intermedio no se altera al recibir datos, ya que la operación de RDMA fija el almacenamiento intermedio y copia el contenido. La aplicación debe manejar el cambio de la posición del almacenamiento intermedio determinando el número de bytes que se han escrito. Utilice el método WorkCompletion.getByteLength() para recuperar información sobre el número de bytes enviados o recibidos correctamente. Estos datos solo son aplicables cuando el estado de finalización es correcto.

Utilización de los métodos PollCQEvent() y getCQEvent()

El método getCQEvent() notifica el código de llamada cuando se recibe un evento en el canal en el que se llama al método. Debe llamar al método PollCQEvent() para recuperar el evento del canal. Emparejando un método getCQEvent() con un método pollCQEvent() puede comprobar si se ha recibido un evento y, posteriormente, recuperarlo. Como alternativa, puede utilizar el método pollCQEvent() de forma independiente porque se devuelve un recuento de sondeo con resultado cero si no hay ningún evento para recuperar. Sin embargo, a diferencia del método getCQEvent(), el método pollCQEvent() ocupa el procesador y utiliza ciclos de procesador. Las aplicaciones pueden optar por utilizar los métodos getCQEvent() y pollCQEvent() de forma conjunta, o sólo el método pollCQEvent().

Eliminación de recursos

La destrucción o eliminación de recursos debe llevarse a cabo en un orden determinado para evitar excepciones. Por ejemplo:
  • Cuando esté preparado para finalizar la comunicación, el servidor o el cliente deben iniciar la desconexión. La desconexión desecha cualquier evento o solicitud destacada antes de eliminar los recursos. La desconexión genera un evento del tipo RDMA_CM_EVENT_DISCONNECTED, que se envía al otro lado de la conexión. Este lado debe iniciar la eliminación de sus recursos. No tiene que volver a llamar al método disconnect().
  • Antes de eliminar un ID de conexión debe eliminar el par de cola asociado mediante el método destroyQueuePair().
  • Se debe eliminar una cola de finalización antes que un canal de finalización.
  • No se puede eliminar un canal de finalización sin un reconocimiento de todas las solicitudes de notificación de colas de finalización. Por lo tanto, cada llamada getCQEvent() correcta debe estar emparejada con una llamada ackCQEvent().
  • No se puede eliminar un canal de evento sin el reconocimiento de todas las solicitudes de conexión. Por lo tanto, cada llamada getConnectionEvent() correcta debe estar emparejada con una llamada ackConnectionEvent().