- Chris Krycho trabajó en LinkedIn durante casi 5 años, a cargo de la infraestructura de frontend y la experiencia de desarrollo de la app web de escritorio, donde vivió el choque entre cambiar de forma segura una base de código a gran escala y las exigencias de ejecutar producto con rapidez
- La app de escritorio de LinkedIn, que al ingresar tenía unas 2 millones de líneas de JavaScript, luego creció hasta convertirse en un monorepo de unas 3.2 millones de líneas, y las migraciones eran prácticamente inviables sin automatización y sin minimizar la carga para los equipos de producto
- La modernización de Ember y la adopción de TypeScript apuntaban a reducir errores y mejorar la calidad del desarrollo; un análisis interno usado para convencer a la organización sostenía que la transición a TypeScript podía reducir al menos un 25% el volumen de errores en los logs de la aplicación
- El plan para pasar de Ember a React enfrentó la estrategia gradual y automatizada de 3 a 5 años del equipo de Chris con un enfoque que buscaba rediseñar mucho más el método existente para acelerar los experimentos de producto
- La respuesta a un incidente de gran escala expuso límites en alertas, observabilidad, resiliencia y revisión de código, y Chris se fue porque la dirección de la organización, centrada ante todo en la velocidad, ya no coincidía con sus valores
El trabajo de 5 años y el tamaño de la base de código
- Chris Krycho se sumó a LinkedIn a fines de enero de 2019 y trabajó allí casi 5 años
- Su área no era la infraestructura de servidores, sino la infraestructura de frontend y la mejora de la experiencia de desarrollo de la app web de escritorio de LinkedIn
- Lideró un proyecto de modernización de JavaScript a gran escala en la app de escritorio, responsable de la experiencia de LinkedIn.com en navegadores no móviles
- La app de su empresa anterior tenía unas 150 mil líneas, pero el frontend de LinkedIn tenía unas 2 millones de líneas de código cuando ingresó
- En la misma app, entre 150 y 200 ingenieros hacían commits cada trimestre, con decenas de equipos desplegando continuamente un único producto
- Cuando entró, había menos de 100 ingenieros remotos entre varios miles en total, y Chris era un caso poco común trabajando de forma remota desde Colorado
Cómo migrar 2 millones de líneas de código
- Una de las primeras tareas grandes fue introducir la sintaxis moderna de clases de JavaScript en el código basado en Ember
- Existía el problema de que las clases antiguas de Ember y las clases nativas de JavaScript se mezclaban en la cadena de herencia; internamente lo llamaban “Zebra Striping”
- Una migración de esta escala debía automatizarse tanto como fuera posible
- Corregir manualmente 2 millones de líneas podía llevar meses o más
- Era difícil pedirles a los equipos de producto que detuvieran el desarrollo de funciones solo para adoptar una nueva sintaxis
- LinkedIn tenía un proceso de iniciativas horizontales (horizontal initiatives) que cruzaban varios equipos, con un principio operativo de mantener la participación de los equipos de producto por debajo del 10%
- El equipo de Chris consideró que sería más fácil de aceptar que el equipo de infraestructura creara PRs mediante automatización y que los equipos de producto se encargaran de revisar y hacer smoke tests, en lugar de pedirles a los equipos de producto que ejecutaran codemods directamente
- El trabajo relacionado con Ember tomó 18 meses en total; la mayor parte avanzó en los primeros 6 meses, pero quedaron rezagos largos por demoras de algunos equipos
El argumento de reducción de errores para convencer sobre TypeScript
- Tras modernizar Ember, el equipo de Chris tomó como siguiente objetivo la gran cantidad de errores de JavaScript generados en el frontend
- LinkedIn manejaba tal volumen de logs de errores que usaba infraestructura interna de logging en lugar de servicios externos
- LinkedIn había superado los 1,000 millones de miembros el año anterior, y cuando Chris se fue el monorepo tenía unas 3.2 millones de líneas
- La mitad era código de pruebas
- La otra mitad era código de producción
- El equipo de Chris analizó por separado las categorías de errores que TypeScript podía detectar
- Algunos errores no podían detectarse ni siquiera con TypeScript, pero estimaban que, al completar la migración, el volumen de logs de la aplicación podría reducirse al menos un 25% dentro de los millones de errores diarios de JavaScript
- El documento de transición a TypeScript escrito por Chris se compartió repetidamente entre ingenieros y managers
- El problema que buscaba resolver
- Los beneficios esperados
- La comparación en competitividad para contratación
- Los criterios para compararlo con otras prioridades
- Más adelante, Chris pasó a cumplir el rol de experto interno para ayudar con problemas difíciles de tipos en TypeScript
De Ember a React: transición gradual y replanteamiento total
- LinkedIn era el mayor usuario de EmberJS del mundo, pero el trabajo de Chris terminó orientándose a planear la migración de Ember a React
- Los líderes senior consideraban que los costos de migración de LinkedIn eran demasiado altos y que frenaban la velocidad de producto
- El plan del equipo de Chris era una estrategia gradual y automatizada de 3 a 5 años
- Reforzar la automatización para que los equipos de producto casi no tuvieran que detenerse
- Separar y migrar en orden el pipeline de build, la capa de datos, la capa de routing, el sistema de reactividad y la capa de vistas
- Al final, cambiar el sistema de renderizado y reactividad de Ember hacia React
- Otro equipo apuntaba de forma más directa al problema de velocidad
- El objetivo era reducir de meses a semanas el tiempo desde una idea hasta un A/B test
- Veían como problema los stacks distintos y los ciclos largos de desktop web, mobile web, iOS y Android
- Chris percibió el enfoque de ese equipo como algo cercano a un modo “finger guns”
- Sentía que no abordaban lo suficiente los problemas que aparecerían al escalar una experiencia que soportaba a decenas de personas para soportar a cientos de ingenieros
- Consideraba que muchas respuestas a sus preguntas eran del estilo “eso no será un problema”
- El plan de 3 a 5 años del equipo de Chris no tuvo buena recepción entre el liderazgo
- El plan en sí era largo y poco emocionante
- El equipo también lo presentó como “la opción menos mala”, por lo que tenía poca fuerza persuasiva
Problemas de resiliencia expuestos durante la respuesta a un incidente
- Después de que Chris volvió de sus vacaciones de Navidad, ocurrió un problema por el cual algunos usuarios de LinkedIn no podían ver páginas de LinkedIn.com durante hasta unos 20 minutos
- El problema estaba relacionado con un servicio de prerenderizado que ejecutaba código de cliente con Node.js para reunir datos del backend y entregarlos rápidamente
- El servicio tenía una fuga de memoria, y cuando un contenedor superaba el límite de memoria, se reiniciaba
- Se combinaron varios factores que ampliaron el incidente
- No había alertas suficientes para los memory kills
- La cantidad de contenedores que podían reiniciarse al mismo tiempo existía como clave en un archivo YAML
- Ese valor era válido desde el punto de vista del tipo, pero era incorrecto para este sistema
- El valor configurado era prácticamente cercano al número total de servicios en ejecución
- Cuando una pausa de despliegues se extendía por un fin de semana largo, los servicios agotaban memoria en momentos similares y se reiniciaban todos a la vez, sin poder atender solicitudes de usuarios
- Si algunos servidores caían, aumentaba la carga sobre los restantes, y el uso de memoria de esos servidores también crecía más rápido, hasta provocar caídas de servidores a nivel de datacenter
- Al mismo tiempo se estaba ejecutando un trabajo de rightsizing para reducir el uso de CPU y memoria de la fleet, por lo que el margen disponible se había reducido
- Chris y otros ingenieros consideraban que hacía falta mejorar alertas, observabilidad y resiliencia
- Un servidor Node en estado runaway no debería tumbar también el proceso host
- Sería más seguro terminar solo el proceso Node, emitir una alerta y reiniciarlo
- También evaluaron una ruta alternativa para pasar a fetch del lado del cliente si el servicio caía
El choque por que la revisión de código no alcanza para evitarlo
- Las reuniones de respuesta al incidente se realizaban varias veces por semana y servían para compartir avances y reportar a ejecutivos
- Un manager de otro equipo asumió la respuesta al incidente y sumó más personal, y Chris lo interpretó como una dinámica en la que no se confiaba en las respuestas de él y de su equipo existente
- En ese proceso, un ingeniero senior preguntó: “¿por qué la revisión de código no pudo resolver esto?”
- Chris consideraba que solo con revisión de código no se podía garantizar que lo mismo no volviera a ocurrir
- Las personas se equivocan
- Para un ingeniero junior es difícil cuestionar si una configuración en el PR de un SRE muy senior es razonable
- El sistema debe operar de forma segura no solo en el mejor día de un ingeniero senior, sino también en el mal día de un ingeniero junior
- Para Chris, la ingeniería de software incluye también el diseño de sistemas que apoyan a los ingenieros que entregan resultados de producto
- Las fallas técnicas y la comunicación organizacional no estaban separadas y, como dice Charity Majors, en niveles altos no existen problemas puramente sociales ni puramente técnicos
Liderazgo, cultura remota y choque de valores
- Chris sentía que su equipo y su enfoque habían sido desplazados por la propuesta de otro equipo
- El plan del otro equipo creció hacia una reconsideración tanto de las apps desktop como móviles, y pasó a revisar en general la forma en que LinkedIn construía producto
- Chris quería mejorar esa propuesta, pero sentía que sus inquietudes y preguntas no eran recibidas lo suficiente
- Dice que un manager le dijo: “eres demasiado idealista, no te preocupas lo suficiente por el balance costo-beneficio y tienes que cambiar tus valores”
- Chris consideraba que el trabajo remoto había influido en la construcción de relaciones
- LinkedIn tenía una fuerte cultura presencial, y muchas personas construían relaciones de forma natural en cafeterías o pasillos
- Sentía que el contacto físico repetido con ingenieros senior y ejecutivos podía marcar una diferencia en situaciones de conflicto
- Chris también reconoció que él mismo tenía debilidades en la construcción de relaciones
Por qué finalmente se fue
- Chris consideraba que muchos problemas de la base de código existente eran resultado de sobrevalorar la velocidad y no corregir ni eliminar los problemas de las rutas secundarias
- Concluyó que, cuando la velocidad se vuelve el valor prioritario, se puede ganar velocidad al inicio, pero se vuelve difícil sostenerla con el tiempo
- Contó que en un trabajo anterior sufrió burnout, con migrañas intensas, dolor abdominal, incapacidad para hacer ejercicio, llanto repentino y ataques de pánico
- Pensó que, si seguía trabajando en LinkedIn, continuaría en un estado en el que tendría que esforzarse todos los días por no estar enojado
- Comparó la situación con intentar cambiar el rumbo de una organización enorme desde un pequeño bote de remos, y decidió no dedicar años a métodos y trabajos en los que no creía
- Chris aprendió en LinkedIn sobre apps de 3 millones de líneas, migraciones a TypeScript en grandes empresas y problemas de ingeniería a gran escala, pero se fue para buscar trabajo alineado con sus valores
1 comentarios
Opiniones de Hacker News
Creo que la parte más interesante del podcast fue el feedback de que era “demasiado idealista, no prestaba suficiente atención a las ganancias y pérdidas, y tenía que cambiar sus valores”. Ya tenía esa impresión antes de leerlo, y por momentos suena como si hubiera recibido feedback valioso, pero lo hubiera ignorado a propósito.
Lo difícil para un senior staff engineer no es “tener razón” en sí, sino lograr la alineación de toda la organización hacia la solución correcta. Como participé en 2019 en el trabajo de reescribir facebook.com en React, esta historia me resultó especialmente interesante.
Logré comunicarme hasta cierto punto, pero mientras estuve en LinkedIn no tuve mucho éxito con esa alineación. Parte de eso es responsabilidad mía, y parte también es responsabilidad de LinkedIn.
Dicho eso, en este caso “demasiado idealista” realmente significaba “no te preocupes por lo que no contribuya directamente a las ganancias y pérdidas”, y rechazo eso hasta la médula. Las ganancias y pérdidas importan, pero también importan la experiencia de usuario, la experiencia de desarrolladores y la ética básica sobre qué estamos construyendo.
En una organización, uno defiende lo mejor posible aquello que cree correcto, y otra persona o un órgano de consenso decide si está de acuerdo. Aceptar ese resultado, negociar un compromiso o irme es decisión mía, y en mi carrera he hecho ambas cosas.
En un unicornio conocido había un senior staff engineer muy inteligente, razonable y amable. Impulsó subir de v2 a v3 un framework en el que se gastaban 50 millones de dólares al año, y comparado con pasar de Python 2 a 3 era un cambio muy menor.
Aunque la investigación mostraba que básicamente se podía esperar una mejora de rendimiento del 10%, la dirección no quería “perder tiempo en una actualización de versión”. Al final, ese ingeniero lo empujó solo, armó una versión preliminar en menos de un mes y, en menos de dos meses, migró parte del trabajo de mayor impacto, ahorrando varias veces su propio salario.
Una vez pagados los costos políticos y de ingeniería iniciales, todos quisieron migrar, y cuando el despliegue terminó un año después, cerca de la mitad de la estructura de gestión mencionada arriba había sido despedida o se había ido, pero el ingeniero y la migración seguían ahí. A veces un staff engineer no está siendo terco, sino que puede ser la única persona cuerda en un mundo enloquecido.
He estado en ese lugar y pude no participar, pero no siempre se puede hacer eso.
He visto casos en los que, sin tener la mejor idea ni el mejor plan, alguien convence a la dirección con las conexiones correctas, el almuerzo correcto y las palabras correctas.
Decir “eres demasiado idealista y no te preocupas lo suficiente por las ganancias y pérdidas” también puede ser una etiqueta para desplazar a alguien. Más aún si quien lo dice es alguien que ha vendido así a sus superiores tanto a sí mismo como sus ideas.
Personalmente, en una organización más chica que Facebook pero con cientos de ingenieros y una gran base de código, hice varias migraciones y actualizaciones de gran escala relacionadas con Ruby, Rails y Postgres, y la metodología que describe Chris es muy razonable y coincide con la forma en que sentí que tuve éxito.
Estoy de acuerdo en que un rol de liderazgo necesita confianza y respeto para ser efectivo. Claro que, para que esa confianza sea útil, también hay que estar en lo correcto. Avanzar en la dirección equivocada no es avanzar.
Nunca he trabajado con la base de código de LinkedIn ni la conozco, pero he visto varias veces bases de código y estructuras organizacionales y políticas que suenan aterradoramente parecidas. Por eso, en general, defiendo el enfoque de finger guns
Una reescritura al estilo finger guns también puede implementarse bien. Si hay varios clientes que hacen lo mismo, uno de ellos puede tomarse como base para otra plataforma y, aunque se empiece de cero, puede hacerse de forma limpia, rápida y concisa
La clave del éxito es poner el nuevo sistema en manos de un equipo pequeño de veteranos que sean expertos del dominio y expertos técnicos. Es polémico, pero creo que todo éxito, incluso los problemas ordinarios de mantenimiento operativo, viene de ahí. Lo demás solo ralentiza
El gran problema que repite la mayoría de los ejecutivos técnicos es que encargan el siguiente gran sistema a las personas con menos experiencia. También me gustaría escuchar una entrevista simétrica desde el lado de finger guns
Es natural, porque son cosas probadas que ya les funcionaron, pero no siempre son lo mejor. Además, aunque un equipo de veteranos inicie un proyecto, rara vez se queda hasta el final, y si no tiene que hacerse cargo del resultado ni de las consecuencias, tomar decisiones es demasiado fácil
El plan debe tener opciones realistas para lidiar con los obstáculos, y eso incluye no solo opciones técnicas, sino también el tiempo y la capacidad de las personas que harán el trabajo. Por ejemplo, si el plan es que varios equipos operen servidores, puede ser técnicamente posible, pero si los equipos no tienen tiempo ni capacidad, no es una opción realista
Por otro lado, también es malo planear una ruta sofisticada que esquive todos los obstáculos. Para cuando llegues, los obstáculos pueden haberse movido, y puede haber obstáculos en el camino que aún no conoces. Si planeaste un solo camino, te quedas detenido ahí
Dicho eso, lo que estamos viendo ahora es una explicación de podcast que resume como caricatura un debate complejo de arquitectura, así que no se puede saber qué falacia de hombre de paja estuvo más cerca de lo que realmente pasó en LinkedIn
Según dijo, el directorio le dijo a toda ingeniería que, de ahí en adelante, en ningún proyecto nadie podría dictar los detalles
Suena a que Chris tomó varias decisiones desafortunadas. Propuso un plan a 5 años, llevó el incidente hacia la culpa en lugar del liderazgo, habló más del problema de lo que lo resolvió y parece que también le faltó construir relaciones
Aunque empatizo con Chris, también parece que no sabía cómo lograr resultados en ese entorno. Y eso está bien. No todo el mundo tiene que aprender a trabajar dentro de nudos burocráticos, y las startups son más simples en ese sentido
Hay una razón por la que las grandes empresas, con el tiempo, pierden filo, y por la que algún ejecutivo termina enfrentando en una sala de reuniones una pérdida de -10% interanual sin un solo vicepresidente que le hable con franqueza
Cuando uno está en una situación así, psicológicamente pierde el sentido de orientación. Siento que tengo razón, ¿pero de verdad la tengo? ¿La gente a mi alrededor es realmente tan incompetente y tan poco interesada en aprender de sus colegas?
Años después, cuando te vas y miras hacia atrás, esas personas fueron despedidas o se fueron, la organización sigue sin poder hacer X, y la agilidad y capacidad de los equipos que se incorporaron después realmente existían
Por un lado, puede ser arrogancia, incompetencia política o incapacidad de adaptarse a una cultura de trabajo patológica. Por otro, puede que esa sea la reacción correcta
Si una organización está pasando por una fase cultural patológica, quizá tenga sentido que personas talentosas, prudentes y apasionadas se vuelvan locas por eso. Quienes no se vuelven locos por eso quizá sean irrelevantes para la productividad y el crecimiento o, peor aún, una pérdida neta
Por eso estos entornos se convierten en psicodramas. ¿La situación es realmente tan mala o estoy sobrerreaccionando?
Pero también era el único plan que sentíamos que podíamos presentar en una situación donde los ejecutivos decían: “aunque sea una migración que nosotros pedimos, no reduzcan en absoluto la velocidad de iteración del producto”
No sé bien a qué se refiere la parte de que llevé el incidente hacia la culpa. Más bien intenté hacer lo contrario, y no culpé a la persona que bajó el umbral de memoria ni a la que escribió por error un valor incorrecto en el YAML. Solo insistí en que no dejáramos la causa raíz abandonada hasta que le explotara a la siguiente persona, sino que la resolviéramos de verdad
Tampoco entiendo bien la parte de que hablé en vez de resolver el problema. Simplemente no me puse a presumir extensamente en el programa sobre lo que logré, pero los problemas que resolví ahí quedaron bastante bien resueltos
La falta de construcción de relaciones fue, como dije en el episodio, mi punto más débil. Tenía buenas relaciones con los ingenieros, pero fracasé bastante en construir confianza política especialmente con los niveles superiores de management
Aun así, no creo que todo se reduzca simplemente a que no sabía cómo lograr resultados en ese entorno. Veía una forma de tener éxito, pero también elegí no actuar de una manera en la que no creía. Muchos de los ingenieros que respeto hacen el baile político por cosas en las que creen, pero no lo hacen por cosas en las que no creen
Actualmente trabajo en LinkedIn. El rol de Chris y el podcast parecen tratar sobre Ember y desarrollo web frontend, y la cantidad de líneas de código y las builds que menciona probablemente correspondan a voyager-web, la app web monolítica principal de LinkedIn.
En LinkedIn hay otros sistemas con millones de líneas de código y builds largas. La capa intermedia, el stack de datos offline, el sistema de métricas y cosas como KafkaKafkaKafka.
Lamentablemente, una build de 17 minutos es bastante buena. Si son 17 minutos sin fallas temporales de infraestructura, está muy bien.
En toda la empresa casi no existe el concepto de testing y tampoco hay QA. Los ingenieros meten proyectos a medio cocinar para ponerlos en sus materiales de ascenso y luego pasan a lo siguiente.
Al usar herramientas internas todos los días, había que resolver demasiados problemas por cuenta propia, y los ingenieros que intentaban trabajar terminaban siendo, en la práctica, QA.
En cambio, habría que apuntar a hacer que las builds sean rápidas o a que la infraestructura de build sea más rápida y barata.
Al menos en el equipo en el que estuve se hacía bastante énfasis en la calidad del código y la cultura seguía mejorando. Eso sí, una vez trabajé en algo de voyager y lo recuerdo como una pesadilla.
Las reescrituras a gran escala son riesgosas incluso en codebases manejables, y los restos que quedan parecen no desaparecer nunca del todo. ¿Quién querría ganar puntos reescribiendo una página de configuración olvidada en un rincón años después?
He visto tantos intentos de este tipo que uno pensaría que debería existir un framework para reescribir codebases, pero no lo hay. Las herramientas de modificación automática de código exigen consistencia, pero son pocos los lugares que la mantienen. Los patrones de código evolucionan tanto con el tiempo que se siente como mirar los anillos de un árbol.
Básicamente estamos poniendo código en cajas, reorganizando esas cajas y diciendo, con argumentos razonables, que cierta disposición es más eficiente. Entonces, ¿por qué no hemos encontrado una mejor manera? La automatización funciona a nivel de código, pero no a nivel de cajas.
Este es un caso de la ley de Conway en acción. Como la organización no cambió, es probable que vuelvan a crear la misma sopa de código.
Habiendo estado en el mismo barco, las iniciativas de ingeniería positivas tienen que venir de arriba hacia abajo, con un patrocinador en una posición muy alta. No se puede cambiar la organización de abajo hacia arriba, y al final es la organización la que crea la codebase.
La ley de Conway no cambia, pero no necesariamente depende solo del organigrama formal. Se puede manejar creando estructuras temporales de comunicación entre los tech leads adecuados y managers competentes.
Pero basta con que haya en el medio unos pocos managers técnicamente débiles o que quieran construir su propio feudo para que todo se rompa con facilidad; y, según el momento del ciclo de vida de la empresa, quizá ya no haya esperanza por la ley de hierro de la burocracia de Pournelle.
Por ejemplo, si todos los desarrolladores son pésimos, les dan un framework popular. Es una excusa para no lidiar con los problemas de personas, como permitir que los niños administren la guardería.
Si quieres excelencia, debes fijar estándares altos con reglas que exijan rendición de cuentas e impongan propiedad, recompensas y responsabilidades. No es complicado, pero desde arriba se necesita firmeza y no tenerle miedo al conflicto.
Aunque puede hacerles perder toda esperanza de que una empresa como Microsoft construya algo y luego no lo arruine.
Pasé 12 años en LinkedIn. Tristemente, está muy lejos de la organización de ingeniería que fue antes. La época en que Kevin Scott lideraba ingeniería fue realmente buena en comparación.
¿Millones de líneas de JavaScript? Eso es la encarnación misma de la hinchazón.
He estado pensando en volver a implementar algo como LinkedIn o, más precisamente, en crear mi propia base de datos de contactos sin funcionalidades “a lo Facebook”.
El problema es cómo lograr que mis contactos se muden en masa. Más allá de la hinchazón, el principal problema de Microsoft LinkedIn es que no te permite exportar la información de tus contactos, y para una plataforma de contactos esa debería ser una función esencial.
https://queue.acm.org/detail.cfm?id=2567673
Resumen: https://www.pixelstech.net/article/1395463142-Why-does-Linke...
LinkedIn migró a Node a comienzos de 2010.
Aunque, viendo las reacciones en este hilo, también me pregunto si esa cifra estaba equivocada.
No lo he hecho con LinkedIn, pero es un truco sucio que uso para exportar listas de asistentes a conferencias publicadas en sitios web públicos. Puede depender del caso.
Me impresionó la forma en que Chris Krycho habla con honestidad de sus dificultades sin convertirlo en un juego de culpas. CoRecursive es uno de mis podcasts favoritos porque trata los contextos complejos detrás del código.
Suena como uno de esos roles de liderazgo blando que casi siempre son difíciles. Tienes “responsabilidad” sobre algo, pero poca o ninguna autoridad sobre el resto de la organización.
Si existe un liderazgo técnico real, puede que esté ausente, o que lleve mucho tiempo ahí y, aunque sea “experto en el sistema”, ya no esté realmente conectado con los problemas reales. Ya lo viví y no lo volvería a aceptar.