(ESPAÑOL ABAJO)
Hello comrades!
Finally, a new Downloader version is here—and this one is a big release. This is the most significant update since its inception, featuring an almost complete rewrite of the application (excluding the test suites). The goal? To push the MiSTer platform's updating process to its limits by adopting a new worker-based architecture.
Why changing the architecture matters
Political jokes aside, this new worker-based architecture is designed to maximize parallelism—not just during the file-fetching process (which has been parallel since Release 1.6), but across all stages of the update process.
Previously, Downloader handled tasks in sequential phases: 1. Fetch all databases. 2. Check the filesystem for changes. 3. Determine files that needed updating and where they should go. 4. Download all files in parallel.While the final step was already fast, the earlier steps created bottlenecks, meaning the system wasn't as efficient as it could be.
Instead of handling these steps separately, each database fetch now triggers a dynamic flow of tasks. These tasks are placed in a job queue, which multiple workers process simultaneously. Workers continuously take on new jobs as they complete old ones, consuming and producing tasks until there's nothing left to do. The update process now runs fully in parallel, eliminating unnecessary wait times and significantly improving efficiency.
Here is a generic depiction of this worker-based architecture.
Concurrency is one of the trickiest aspects of programming, and getting it wrong can introduce race conditions, deadlocks, and unpredictable behavior. In other words, bugs that are super hard to catch and fix. So, this rewrite wasn’t just about making things faster—it had to be done right.
This wasn’t an overnight decision. In fact, I had planned this approach since Release 1.0 back in the summer of 2021 (time flies!). Back then, I focused on rapidly implementing features—even if that meant for the code to become a bit more "quick and dirty" at times—while investing heavily on writing high-quality test suites with top level test coverage. This strategic choice allowed me to later rewrite the core while keeping all features intact, using test-driven development (TDD) to verify that everything still worked exactly as before in the new codebase.
The result is a clearer and more maintainable system that not only runs faster today but also makes the future optimizations and new features much easier to implement. It took me around four months of full-time work—a serious effort, but one that’s already paying off. Future updates will now come at a much faster pace than ever before.
Speed improvements
The most immediate benefit of this release is a significantly faster update process in all scenarios. To illustrate the impact, I’ll share some benchmark results comparing the new Release 2.0 with the previous Release 1.8.
Benchmark: Installing 20,000+ Files
In this test, Downloader installs over 20,000 files, and each version was run 50 times in an interleaved fashion to ensure fair comparisons. Below are the results:
- Top graph: A histogram showing how most updates in the new version complete much faster than in the old version.- Bottom graph: A scatter plot displaying all measurements, with a dashed line marking the average execution time.
These results reflect the inherent variability of network speeds, which can be influenced by your internet provider, local router traffic, and other external factors. Even with these fluctuations, the overall speed improvement is nearly 20%—a noticeable upgrade.
Benchmark: The "0 Files" Scenario
The most important scenario, in my opinion, is when Downloader finds nothing to update—which is also similar to cases where only 1–4 updates are needed. This situation occurs frequently in real-world usage, so optimizing it has a major impact on everyday performance.
Here are the results:
The difference is much more pronounced than in the large-update test. The blobs in the graph show a clear and noticeable separation between the two versions.
On average, Release 2.0 is over 25% faster in these cases—a speed boost you’ll definitely notice every time you run Downloader.
Closing up
With these improvements and the new worker-based architecture, this release is officially the fastest version of Downloader yet.
You'll receive the update as part of the [distribution_mister] database—which is always active by default—so the first update will still run using the older Downloader version. If you’re curious, you can always check the version number in the logs to confirm when the new version takes over.
If you want to see the LONG full list of improvements and bug fixes, with all the details, please check the CHANGELOG.
I'll be rolling out more updates pretty soon. Until then, have a good one!
ESPAÑOL
¡Hola camaradas!
Finalmente, ha llegado una nueva versión de Downloader, ¡y esta es una gran Release! Esta es la actualización más significativa desde sus inicios, con una reescritura casi completa de la aplicación (exceptuando las suites de tests). ¿El objetivo? Llevar el proceso de actualización de la plataforma MiSTer a su máximo potencial adoptando una nueva arquitectura basada en “trabajadores” (workers en inglés).
Por qué el cambio de arquitectura importa
Bromas políticas aparte, esta nueva arquitectura basada en “trabajadores” está diseñada para maximizar el paralelismo, no solo durante la obtención de archivos (que ya se hacía en paralelo desde el Release 1.6), sino en todas las etapas del proceso de actualización.
Hasta ahora, Downloader manejaba las tareas en fases secuenciales:
Obtener todas las bases de datos.
Revisar el sistema de archivos en busca de cambios.
Determinar qué archivos necesitaban actualización y dónde debían ubicarse.
Descargar todos los archivos en paralelo.
Si bien el último paso ya era rápido, las fases anteriores creaban cuellos de botella, haciendo que el sistema no fuera tan eficiente como podría ser.
En lugar de manejar estos pasos por separado, ahora cada descarga de una base de datos desencadena un flujo dinámico de tareas. Dichas tareas se colocan en una cola de trabajos (job queue), que varios “workers” procesan simultáneamente. Estos “workers” toman continuamente nuevos trabajos a medida que completan los anteriores, consumiendo y produciendo tareas hasta que ya no queda nada por hacer. El proceso de actualización ahora corre completamente en paralelo, eliminando tiempos de espera innecesarios y mejorando significativamente la eficiencia.
Aquí hay una representación genérica de esta arquitectura basada en “workers”.
La concurrencia es uno de los aspectos más complicados de la programación; hacerlo mal puede introducir condiciones de carrera, bloqueos (deadlocks) y comportamientos impredecibles. En otras palabras, errores muy difíciles de encontrar y corregir. Así que esta reescritura no solo buscaba más velocidad, sino hacerlo bien.
No fue una decisión de la noche a la mañana. De hecho, había planeado este enfoque desde el Release 1.0 en el verano de 2021 (¡el tiempo vuela!). En aquel entonces, me enfoqué en implementar rápidamente las funciones —aunque eso significara que el código fuera a veces más “chapucero”—, mientras invertía mucho en escribir suites de tests de alta calidad con una cobertura de código de primer nivel. Esta elección estratégica me permitió avanzar rápido al inicio para reescribir más tarde el núcleo de la aplicación manteniendo todas las funciones intactas, gracias al uso del desarrollo guiado por pruebas (TDD), que me permitía verificar que todo siguiera funcionando exactamente igual en el nuevo código.
El resultado es un sistema más claro y más fácil de mantener que, además de funcionar más rápido hoy, facilitará las optimizaciones futuras y la implementación de nuevas funciones. Me tomó alrededor de cuatro meses de trabajo a tiempo completo —un gran esfuerzo, pero que ya está dando frutos. Las futuras actualizaciones ahora saldrán mucho más rápido que antes.
Mejoras de velocidad
El beneficio más inmediato de este Release es un proceso de actualización notablemente más veloz en todos los escenarios. Para ilustrar el impacto, compartiré algunos resultados de referencia comparando el nuevo Release 2.0 con el anterior Release 1.8.
Benchmark: Instalando más de 20,000 archivos
En esta prueba, Downloader instala más de 20,000 archivos, y cada versión se ejecutó 50 veces de manera intercalada para asegurar comparaciones justas. A continuación, los resultados:
Gráfico superior: un histograma que muestra cómo la mayoría de las actualizaciones en la nueva versión se completan mucho más rápido que en la versión antigua.
Gráfico inferior: un diagrama de dispersión que muestra todas las mediciones, con una línea discontinua indicando el tiempo de ejecución promedio.
Estos resultados reflejan la variabilidad inherente de las velocidades de red, influenciadas por tu proveedor de internet, el tráfico de tu router local y otros factores externos. Incluso con esas fluctuaciones, la mejora total de velocidad se acerca al 20%, un avance perceptible.
Benchmark: El escenario de “0 archivos”
El escenario más importante, en mi opinión, es cuando Downloader no encuentra nada que actualizar—lo que también se parece a los casos en los que solo hay 1–4 archivos para actualizar. Esta situación ocurre con frecuencia en el uso diario, por lo que optimizarla tiene un gran impacto en el rendimiento cotidiano.
Aquí están los resultados:
La diferencia es mucho más pronunciada que en la prueba de actualización masiva. Las barras en el gráfico muestran una separación clara y notable entre las dos versiones.
En promedio, el Release 2.0 es más de un 25% más rápido en estos casos, una mejora de velocidad que notarás cada vez que ejecutes Downloader.
Para terminar
Con estas mejoras y la nueva arquitectura basada en “workers”, este Release es oficialmente la versión más rápida de Downloader hasta la fecha.
Recibirás la nueva versión como parte de la base de datos [distribution_mister], que está activa por defecto, así que la primera actualización todavía se realizará con la versión anterior de Downloader.
Si te interesa, siempre puedes verificar el número de versión en la salida por pantalla del final de la ejecución para confirmar cuándo entra en vigor la nueva versión.
Si quieres ver la lista LARGA de mejoras y correcciones de errores, con todos los detalles, por favor revisa el CHANGELOG (en inglés).
Pronto publicaré más actualizaciones. ¡Que vaya bien!