ruby - ¿Cómo puedo generar programáticamente nombres de subdominio similares a Heroku?
heroku dashboard login (3)
Hay varias posibilidades.
Puedes generar una cadena aleatoria .
Si quieres usar palabras reales, necesitas un diccionario. Luego puedes crear un resultado generando una permutación de palabras y dígitos.
Otra buena alternativa es la que adoptó Ruote . Ruote confía en rufus-mnemo para generar un nombre único para cada proceso. rufus-mnemo
proporciona métodos para convertir el número entero en "palabras" más fáciles de recordar y viceversa.
Puede generar una identificación única para el registro y luego convertirla en una palabra.
Todos hemos visto los subdominios interesantes que te asignan automáticamente cuando implementas una aplicación en Heroku con un "heroku create" desnudo.
Algunos ejemplos: blazing-mist-4652, electric-night-4641, morning-frost-5543, radiant-river-7322, y así sucesivamente.
Parece que todos siguen un patrón adjetivo-sustantivo-4digitnumber (en su mayor parte). ¿Simplemente escribieron un diccionario de algunos adjetivos y sustantivos, y luego eligen combinaciones de ellos al azar cuando presionas una aplicación? ¿Hay una gema Ruby que logra esto, tal vez proporciona un diccionario que uno puede buscar por partes del discurso, o es algo que se debe hacer manualmente?
Ingeniero en el equipo de Heroku API aquí: fuimos con el enfoque más simple para generar nombres de aplicaciones, que es básicamente lo que sugirió: mantener matrices de adjetivos y sustantivos en la memoria, elegir un elemento de cada uno al azar y combinarlo con un número aleatorio de 1000 a 9999.
No es el código más emocionante que he escrito, pero es interesante ver lo que teníamos que hacer para escalar esto:
Al principio estábamos eligiendo un nombre, tratando de
INSERT
y luego rescatando el error de restricción de exclusividad para elegir un nombre diferente. Esto funcionó bien cuando teníamos un gran grupo de nombres (y un conjunto no demasiado grande de aplicaciones que los usaban), pero a cierta escala comenzamos a notar muchas colisiones durante la generación del nombre.Para hacerlo más resistente, decidimos elegir varios nombres y verificar cuáles están todavía disponibles con una sola consulta. Obviamente, todavía necesitamos verificar los errores y volver a intentarlo debido a las condiciones de la carrera, pero con tantas aplicaciones en la mesa, esto es claramente más efectivo.
También tiene el beneficio adicional de proporcionar un gancho fácil para que podamos obtener una alerta si nuestro grupo de nombres es bajo (por ejemplo: si se toman 1/3 de los nombres aleatorios, envíe una alerta).
La primera vez que tuvimos problemas con las colisiones aumentamos radicalmente el tamaño de nuestro grupo de nombres al pasar de 2 dígitos a 4. Con 61 adjetivos y 74 sustantivos, esto nos llevó de ~ 400k a ~ 40mi nombres (
61 * 74 * 8999
).Pero cuando ejecutamos 2 millones de aplicaciones comenzamos a recibir alertas de colisión nuevamente, y a un ritmo mucho más alto de lo esperado: Cerca de la mitad de los nombres colisionaban, lo que no tenía sentido considerando el tamaño de nuestro grupo y la cantidad de aplicaciones en ejecución.
El culpable, como habrás adivinado, es que
rand
es un generador de números pseudoaleatorio bastante malo. Elegir elementos y números aleatorios conSecureRandom
redujo radicalmente la cantidad de colisiones, haciendo que coincidiera con lo que esperábamos en primer lugar.
Con tanto trabajo para escalar este enfoque, tuvimos que preguntarnos si hay una mejor manera de generar nombres en primer lugar. Algunas de las ideas discutidas fueron:
Haga que la generación del nombre sea una función de la id de la aplicación. Esto sería mucho más rápido y evitaría el problema de las colisiones por completo, pero a la baja perdería muchos nombres con las aplicaciones eliminadas (y maldición, tenemos MUCHAS aplicaciones que se crean y eliminan poco después como parte de diferentes pruebas de integración) .
Otra opción para hacer que la generación de nombres sea determinista es tener el grupo de nombres disponibles en la base de datos. Esto haría que sea fácil hacer cosas como reutilizar un nombre solo dos semanas después de que se eliminó la aplicación.
¡Estamos emocionados de ver qué haremos la próxima vez que se active la alerta de colisión!
Espero que esto ayude a cualquiera que trabaje en la generación de nombres amigables.
RandomUsername una joya para hacer esto: RandomUsername