Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimización de claimUserTickets: Mejora de rendimiento y refactorización #273

Closed
wants to merge 3 commits into from

Conversation

TextC0de
Copy link
Collaborator

Este PR optimiza la función claimUserTicket, mejorando su rendimiento y simplificando su lógica.
Los cambios principales incluyen:

  1. Eliminación de verificaciones redundantes:

    • Se eliminó la verificación inicial de la cantidad de tickets disponibles.
    • Se mantiene la verificación final para garantizar la integridad de los datos.
  2. Paralelización de operaciones:

    • Se utilizan Promise.all para ejecutar consultas en paralelo, reduciendo el tiempo de espera.
  3. Optimización de consultas a la base de datos:

    • Se reemplazaron múltiples consultas individuales por consultas en lote más eficientes.

Detalle pruebas de rendimiento

Se realizaron 15 iteraciones de los tests encontrados en src/schema/userTickets/tests/claimUserTicket
Se hizo un análisis del rendimiento de los tests y estos fueron los resultados.

Versión main (actual en producción):

  • Duración promedio: 3.93 segundos
  • Rango: 3.82 - 4.29 segundos

Nueva versión (textcode/improve-purchase-order-performance):

  • Duración promedio: 3.89 segundos
  • Rango: 3.75 - 4.05 segundos

Mejora de rendimiento: 1.02%

Resumen de pruebas de rendimiento

La nueva versión muestra una mejora ligera pero consistente en el rendimiento.

Aunque la diferencia es pequeña en los tests actuales, es importante notar que:

  1. La mejora se mantiene a lo largo de múltiples ejecuciones.
  2. Los tests actuales operan con una cantidad limitada de tickets, lo que podría estar subestimando el impacto de la optimización en producción con mayor volumen de datos.
  3. Las optimizaciones realizadas, especialmente la paralelización de operaciones con Promise.all y la reducción de consultas a la base de datos, deberían proporcionar beneficios más significativos en entornos de producción con mayor carga.
  4. La reducción de consultas a la base de datos se podría transmitir en menor coste operativo.

Cambios en los tests:

  • Se actualizó el mensaje de error esperado en el test "Should NOT allow claiming > If we would be going over ticket quantity" para reflejar el nuevo comportamiento.

Copy link

github-actions bot commented Sep 18, 2024

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 81.74% 14273 / 17460
🔵 Statements 81.74% 14273 / 17460
🔵 Functions 76.77% 390 / 508
🔵 Branches 79.32% 1028 / 1296
File Coverage
File Stmts % Branch % Funcs % Lines Uncovered Lines
Changed Files
src/datasources/db/userTickets.ts 100% 100% 100% 100%
src/schema/userTickets/helpers.ts 88.92% 79.48% 100% 88.92% 52-57, 62-67, 70-75, 86-91, 136-137, 164-165, 216-217, 251-252
src/schema/userTickets/mutations.ts 86.02% 70.52% 100% 86.02% 99-100, 146-147, 169-170, 211-212, 223-224, 235-236, 283-284, 295-300, 313-318, 321-326, 374-381, 393-398, 465, 492-493, 500-524, 538, 555-556, 577-578, 624-629, 632-637
Generated in workflow #1200

ticketIds,
},
});
const [events, tickets] = await Promise.all([
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Se paralelizaron las consultas de eventos y tickets usando Promise.all.

userId: USER.id,
logger,
}),
trx.query.ticketsSchema.findMany({
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Se eliminó el bucle for que iteraba sobre cada ticket. Ahora procesamos los tickets en lote, lo que reduce el número de consultas a la base de datos y mejora el rendimiento.

.execute();

// Bulk query for existing ticket counts
const finalTicketsCount = await trx
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reemplazamos múltiples consultas individuales por una única consulta en lote para obtener el recuento de tickets. Esto reduce la carga en la base de datos y mejora el tiempo de respuesta.

// If the ticket template has a quantity field, means there's a
// limit to the amount of tickets that can be created. So we check
// if we have enough tickets to fulfill the purchase order.
if (ticketTemplate.quantity) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Se eliminó este check inicial ya que estamos haciendo un check final en el recuento de los userTickets existentes.

Esto mejora el rendimiento para el caso de uso más común de éxito en el que no se rebasa la cantidad máxima de stock

userTicketsSchema.ticketTemplateId,
ticketTemplates.map((t) => t.id),
),
inArray(userTicketsSchema.approvalStatus, [
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aquí me basé en el código anterior en el que se tomaban en cuenta solo estos dos estados, approved y pending, pero tal vez deberíamos tambien tomar en cuenta a:

  • Gifted
  • Gifted accepted
  • Not required

¿Que piensan?

TextC0de added a commit that referenced this pull request Oct 15, 2024
Este PR implementa la funcionalidad de regalo de tickets (relacionado a
#30, #31) y además incorpora optimizaciones de rendimiento propuestas en
el PR #273.

Se incluyen los siguientes cambios principales:

1. Nuevas tablas y relaciones:
- `user_ticket_gifts`: Almacena información sobre los regalos de
tickets.
   - Actualización de `user_tickets` con nuevos estados y relaciones.

2. Endpoints GraphQL:
- Mutación `giftMyTicketToUser`: Permite a un usuario regalar su ticket.
- Mutación `acceptGiftedTicket`: Permite al receptor aceptar un ticket
regalado.
- Query `myTicketGifts`: Obtiene los regalos de tickets enviados o
recibidos por el usuario actual.

3. Lógica de negocio:
- Implementación de validaciones para evitar auto-regalos y exceder
límites de tickets.
- Manejo de estados de regalo (pendiente, aceptado, rechazado,
cancelado, expirado).
   - Cálculo de fechas de expiración para regalos.

4. Servicio de correo electrónico (solo para 9punto5, luego hay que
extenderlo):
- Nuevas plantillas de correo para notificaciones de regalo de tickets.
- Implementación de métodos para enviar correos de confirmación de
regalo y aceptación.

5. Actualizaciones en flujos existentes:
- Modificación de `claimUserTicket` para manejar regalos de tickets
durante la compra.

6. Pruebas:
   - Nuevos tests para cubrir los escenarios de regalo de tickets.

## Optimizaciones de rendimiento (del PR #273):

Dado que estamos añadiendo más complejidad a la mutación `claim`, se han
incorporado las optimizaciones propuestas en el PR #273. Estas incluyen:

- Eliminación de verificaciones redundantes.
- Paralelización de operaciones usando `Promise.all`.
- Optimización de consultas a la base de datos, reemplazando múltiples
consultas individuales por consultas en lote más eficientes.

Estas optimizaciones, aunque no cruciales, son relevantes para mantener
el rendimiento de la mutación `claim` a medida que se añade nueva
funcionalidad.

Cualquier feedback o sugerencia para mejorar la implementación es
bienvenido.
@TextC0de
Copy link
Collaborator Author

Se implementó en #286

@TextC0de TextC0de closed this Oct 26, 2024
@TextC0de TextC0de deleted the textcode/improve-purchase-order-performance branch October 26, 2024 02:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant