El caso Rubiales

Si, se supone que este es un blog de tecnología y no de política y menos de deporte, pero como en agosto hemos estado un poco amodorrados lo más interesante que tengo para hablar es esto… Así que dejaremos aquí mi opinión y ya.

Empecemos por lo más básico: dar un beso no consentido es delito. Lo es en España y lo es en mucho más países donde se considera una agresión sexual, aunque leve. Lo cierto es que muchas veces se trivializa con el tema, o se le quita importancia por herencias culturales que nos dicen que las mujeres están para eso.

Lo que algunos no se explican es cómo la carrera de alguien que gana casi 700.000 Euros al año se puede ir al garete por comportamientos de gañán redomado. Pero no es una cuestión de feminismo o de legalidad, es una cuestión de principios.

A fecha de hoy todavía no se conoce cual será el destino de Rubiales, atrincherado en su cargo, rodeado por su familia y defendido por la recua de desinformadores de la extrema derecha. Lo que está claro, y lo dejó claro en sus declaraciones, es que él no va a dimitir. Lo más normal sería que esperase a que le destituyesen para cobrar las indemnizaciones correspondientes, y mientras, prepara el camino para las inevitables querellas que le van a caer. Lo que si se sabe es que una amplia mayoría de la población no le quiere ver representando a nuestro país en ningún sitio y que la FIFA ya le ha sancionado en ese aspecto. Por lo menos la polarización actual parece que aquí es un poco menos, pero seguimos a la espera de qué harán las «fuerzas vivas» y si dejarán caer a este golfo o le mantendrán como representación de su poder.

La verdad es que este personaje tenía que haber sido cesado hace tiempo por sus corruptelas económicas, pero parece que tenía sostenes muy importantes en el mundo del futbol (no quiero decir quién) y ya se creía como el jefe indiscutible que podía hacer y deshacer a su antojo. Desconozco si es su forma de ser o es que ha tenido alguna alteración hormonal reciente, pero no veo muy normal que se agarre el paquete delante de millones de espectadores y junto a la Reina y la infanta para después plantarle un morreo televisado a una de las jugadoras (que por su orientación sexual tampoco es que lo vaya a apreciar mucho). Imaginaos esto en otros ámbitos fuera del deporte… Que tu jefe te pida un piquito y te lo plante por lo buenos que han sido los resultados trimestrales, que el representante de España en unas negociaciones se toque el paquete celebrando la firma del mismo y que, además, en la emoción del momento agarre a su secretaria y la plante un beso… Inaceptable, ¿no? Pues lo mismo con este sujeto. El futbol puede ser especial, pero no las actitudes de los que representan a un país o de los que tienen un puesto de poder sobre sus subordinados.

Lo que ya hizo este esperpento de persona después de que le pidiesen responsabilidades es de lo más despreciable que se puede imaginar. Presionar a la jugadora y a su familia para que saliesen a defenderle, sacar comunicados falsos haciendo creer que han sido redactados por la víctima, poner su huevos sobre la mesa en un discurso del «no dimito» digno del manual del machista ibérico y, sobre todo, negándose a reconocer que haya hecho algo mal son actos que no deberían quedar impunes.

Varias formas de hacer pruebas de stress a una url

Una vez que hemos programado algo, una web, un api o cualquier otra cosa que van a utilizar muchas personas a la vez nos entra la necesidad inmediata de, después de las pruebas unitarias, poder pasarle unas pruebas de stress para ver cuanta gente puede entrar a la vez antes de que el sistema reviente o, en el peor de los casos, ver si hay algún problema de programación que nos impide tener peticiones concurrentes con seguridad.

Servidor bajo asedio... Imagen generada por AI

Solo os voy a presentar los más sencillos, aunque luego hay herramientas mucho más completas que ya se deben usar en el momento de QA para comprobar si los requisitos del sistema se cumplen (máximo número de peticiones por minuto / curva de carga / evolución del tiempo de respuesta, etc.).. Pero vamos, que ahora mismo solo queremos ver si se puede llamar a nuestro api o web concurrentemente…

siege

Este es el comando más sencillo que he encontrado, pero a la vez es muy eficiente en lo que se puede hacer con él.

siege -c10 -r1 https://blaba.com

Tras un tiempo de ejecución (depende de los parámetros c: concurrencia y r: repeticiones) se recibirá una salida como esta:

{ "transactions": 140,
"availability": 100.00,
"elapsed_time": 3.12,
"data_transferred": 3.48,
"response_time": 0.22,
"transaction_rate": 44.87,
"throughput": 1.11,
"concurrency": 9.68,
"successful_transactions": 140,
"failed_transactions": 0,
"longest_transaction": 0.33,
"shortest_transaction": 0.04
}

Ahí ya podemos ver cual es el ratio de fallo para esa concurrencia y los tiempos máximos y mínimos para cada transacción. Guay…

Ahora bien, el problema viene de que solo podemos hacer peticiones GET (podemos poner las cabeceras que queramos, pero no hay manera de hacer una petición POST, por ejemplo). Así pues si tenemos que probar un API que tiene algo más que peticiones GET tendremos que usar otra cosa…

Sigue habiendo una infinidad de herramientas muy buenas para hacer estas cosas, como Jmeter y otras, pero para unas pruebas de carga básicas vamos a continuar con el camino «barato»

curl + bash

Si estamos en linux, tenemos suerte (el siege también es de linux, pero seguro que hay un port para tu sistema operativo). Apuntad esto:

Primero hay que instalar paralell que no está en la distribución por defecto:

sudo apt install parallel

Luego podremos escribir algo como esto:

seq 100 | parallel --max-args 0 --jobs 10 "./curl_to.sh"

Y en curl_to.sh poned el comando curl con el que vais a probar, por ejemplo este:

curl --location 'https://blabla.com/api/v1/micomando' --header 'Content-Type: application/json' --header 'Accept: application/json' --header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIU...CvuTuF30k8XEFg_XL-gJyK-8rT4htC7HTHxbtDSGN8' --data '{ "userid": "418043893","message": "Hola payo…..", "uuid": "kk"}'

Este comando de antes lo que hace, básicamente, es lanzar una petición POST con un cuerpo JSON y una cabecera de autenticación (con un token JWT por ejemplo). Este código lo podemos sacar de postman, por ejemplo diciendole que queremos generar código para curl.

Si lanzamos el comando seq, lo que hace es generar una secuencia de números (en este caso de 1 a 100, y paralell lo que hace es lanzarnos de manera paralela (10 cada vez) el comando que hemos especificado… Con esto conseguiremos lanzar 100 veces 10 peticiones paralelas.

Obviamente no es perfecto, pero habremos podido simular una carga paralela sin tener que instalar nada en nuestro ordenador. Si eso lo combinamos con el comando time (os lo dejo como ejercicio) también podríamos sacar estadísticas de las ejecuciones.

En próximas entradas veremos como usar algunas herramientas muy potentes para pruebas de carga, pero por ahora, ya podéis empezar a estresar a vuestro servidor.

La pinza

Uno de los grandes logros en la estrategia militar de los alemanes en la segunda guerra mundial fue utilizar el movimiento de pinza con embolsamiento (no había forma de salir de la misma) para acabar de manera rápida con un enemigo que se creía muy bien guarnecido en su territorio.

Este es un movimiento que ya se describe desde tiempos inmemoriales, Tsun Zu ya lo recomienda, pero sin embolsamiento, dejando una salida al enemigo para que no se sienta acorralado y se vea forzado a una lucha más feroz. Y, diréis vosotros, ¿porque nos habla este ahora de un movimiento militar? Bien, porque este movimiento se utiliza en muchos otros campos, uno de ellos, y de actualidad tras las últimas elecciones municipales, es el campo político.

Yo ya os he dicho que soy más progresista que otra cosa, no me importa decirlo aunque no creo en eso de que haya que odiar al que piensa distinto y odio la polarización en la política y en cualquier otro aspecto de la vida. Estamos asistiendo, no obstante, a un espectáculo vergonzoso de prostitución de la democracia en la que los ciudadanos, por el momento, no podemos más que escandalizarnos y desanimarnos. Perdonadme por poner un post de corte político en medio de mi blog, pero es que es mi blog y es el sitio donde dejo lo que me pasa por la cabeza (sea técnico o no).

Estas elecciones municipales han servido para varias cosas, que se han visto desde la campaña y desde antes, a saber:

  • Los medios de comunicación ya no tienen ningún pudor en mostrar a quién apoyan y a quien quieren silenciar. Eso es bastante normal cuando hablamos de una tertulia política, pero es vergonzoso cuando convierten los programas de entretenimiento en adoctrinamiento. Solo hay que ver el programa de Pablo Motos y sus invitados a quién menos gracioso o el hecho de que el horario de la telebasura del corazón la hayan sustituido por telebasura política con Ana Rosa, por poner dos ejemplos del lavado sistemático de cerebros débiles.
  • No existen medios de izquierda ni que se le parezcan. La falsa sensación de que la sexta, por ejemplo, era una televisión «friendly» con la izquierda se ha tornado, como no podía ser de otra manera, en la constatación de que tienen patrones a los que contentar y sus directivos no tienen ningún escrúpulo en participar de las cloacas o de invitar a «hostiles» y silenciar a los «amigos» de la izquierda más irreductible.
  • La derecha no tiene escrúpulos y no hace prisioneros. Lo hemos visto en la defenestración de casado, en el uso de «medios» mentirosos y difunde bulos (okdiario, EDA, etc.) siendo pagados sin rubor con dinero público y compitiendo en quien decía la mentira más gorda (ya sabes, si alguien dice que es mentira es que es un zurdo intentando coartar mi libertad de expresión) y siempre es un buen momento para reirse de los progres.
  • No hay aliados entre los que piensan igual que tu. Sumar, que podría parecer una buena idea a priori, se ha esforzado muy mucho en desligarse de Podemos desde el primer momento. Yolanda Díaz, que está en el gobierno gracias a Podemos, que ha disfrutado de libertad y apoyo constante para su labor de gobierno ha decidido que no quiere cargar con el peso de un partido ya formado, que prefiere alimentarse de estructuras más tradicionales, desmembrarlas y someterlas a un único objetivo: volver a sentarse en un gobierno.
  • Nadie se lee los programas… Votan lo mismo al defensor de los toros y azote de los menas que a la que va de bar en bar sirviendo cervezas y sin encontrarse con el ex-novio. ¿Programa? ¿Para qué? Ya se que me roban, pero yo nunca permitiría que me robase un comunista (Álvaro Ojeda dixit)

Esto ha generado una terrible pinza donde, si te unes a Sumar renuncias a cualquier posibilidad de apoyar políticas más sociales (nada que no haría el PSOE) y, además, sabes que te van a mirar mal como el radical que ya no sabe donde meterse. Si no te unes eres un traidor a la izquierda y solo piensas en tu orgullo y les vas a hacer perder votos. Por otro lado tienes a la derecha lobotomizadora que te está diciendo que no merece seguir votando, total, ellos ya han ganado y «la resistencia es futil», mejor dejar de resistirse y, en todo caso, votar al PSOE (que es lo que Pedro Sanchez ha dado por descontado que hará la mayor parte de la gente como voto útil visto lo que provoca la fragmentación del voto).

Lo que más me duele es que gente aparentemente culta e inteligente como Pedro Vallin van por ahí insultado, ninguneando y mofándose de los que han construido el modo de política que ahora pretenden aprovechar para hacerse un Carmena. Lo que ellos no saben es que, al igual que matar la sanidad pública hará que la privada lo pase muy mal (no está preparada para tener que hacerse caso de las cosas costosas), matar a Podemos hará que la izquierda vuelva a lo de siempre, pero de mal humor. Sumar será la nueva Izquierda Unida (¿Similitudes en la intención del nombre?) y PSOE volverá a aglutinar el voto no de derechas.

Internacionalizando javascript en symfony

En este nuevo desafío que he asumido recientemente me encuentro con tener que mantener y mejorar aplicaciones web que están desarrolladas sobre symfony 5. Este es un framework PHP (si, php, no me matéis) que tiene sus cosas buenas y sus cosas malas. Una de las buenas es que permite internacionalizar las aplicaciones sin demasiados problemas… Al menos la parte de html.

Symfony utiliza un sistema de plantillas twig que es donde se pueden realizar las traducciones poniendo {%trans%}cadena{%endtrans%} y luego simplemente tenemos que mantener los archivos de traducción de cada lenguaje y ya toda la magia sucede internamente y sin problemas.

Imagen generada por AI cuando le pedí que me hiciese una imagen para un post de programación

Pero, ¿Qué pasa con las cadenas que generamos en javascript? Los archivos .js se sirven estáticamente sin que pasen por el proceso de sustitución que se hace en los twig, no nos vale poner {%trans%}cadena{%endtrans%} en el js porque ese archivo nunca va a ser tratado por symfony ni por php ya puestos.

La solución que he terminado por implementar se basa en generar un archivo .js con las traducciones en base a una plantilla twig y cargarla cada vez que necesite traducir algo en un js. Para ello solo tenemos que dar estos pasos:

  1. Crear la ruta en routes.yml (o usar un decorador) para /jstrans.js o similar
  2. Crear un controlador para servir ese archivo, por ejemplo JavascriptController.php
  3. Crear un twig para el javascript, por ejemplo jstrans.js.twig
  4. Meter en el twig todas las cadenas y sus traducciones correspondientes
  5. Hacer que jstrans.js se cargue en todas las páginas que necesiten traducciones
  6. usar la función que traduce en los js que lo necesiten.

Aquí os dejo un ejemplo de cada uno de los archivos:

JavascriptController.php

class JavascriptController extends AbstractController
{
    public function __construct()
    {
        $this->config = new Config();
    }

    public function index(): Response
    {
        $response =  $this->render('javascript/jstrans.js.twig', [
            'controller_name' => 'JavascriptController',
        ])->setSharedMaxAge(3600)->setPublic();
        $response->headers->set('Content-Type','text/javascript');
        return $response;
    }
}

jstrans.js.twig

if (typeof jstrans == 'undefined') {

    var jstrans = {
        traducciones: {
            'Seleccionar': '{%trans%}Seleccionar{%endtrans%}',
            'Registros': '{%trans%}Registros{%endtrans%}',
            'No se han encontrado resultados': '{%trans%}No se han encontrado resultados{%endtrans%}',
        },
        // Función que traduce un texto
        translate: function (text) {
            if (jstrans.traducciones[text] != undefined) {
                return jstrans.traducciones[text];
            } else {
                return text;
            }
        }
    };
} else {
    console.log ('jstrans ya está definida');
}

Luego ya se meten las cadenas en, messages.en.yaml,, por ejemplo

Seleccionar: Select
Registros: Registers
No se han encontrado resultados: No results found

Y luego solo hay que usarlo en los archivos js de esta manera:

jstrans.translate("Seleccionar")

Y eso te dará la cadena traducida al idioma en el que se esté navegando.

¿Conoces algún método mejor para conseguir traducciones en los js de un proyecto symfony? déjame un comentario si es así…

Buscar talento en linkedin

Durante mi periodo de CEO en biblioeteca he tenido la necesidad de contratar personas que pudiesen ayudarnos con los proyectos que nuestros clientes nos proponían. En este mercado la rotación es muy alta y el talento (aunque cueste admitirlo) bastante escaso. Tampoco es que nosotros tengamos necesidades extraordinarias, y la mayor parte de nuestras contrataciones venían recomendadas de antes (eso siempre es lo mejor), pero cuando hay que cubrir puestos rápidamente es cuando nos encontramos en problemas.

Uno de los sitios a los que he acudido a ofrecer puestos de trabajo ha sido a LinkedIn, en concreto creo que conseguí un total de 4 personas (en un periodo largo), pero cada vez ha estado funcionando peor, os comento el ejemplo de la última campaña donde buscaba alguien con Java y Linux (y tampoco pedía años de experiencia). El anuncio en concreto está en este enlace:

https://www.linkedin.com/jobs/view/3517177902/

Para esta oferta recibí estos resultados:

Recibí un total de 7 cvs, de los que ninguno era adecuado del todo.

Pero hagamos unas pequeñas cuentas… 100 Euros de gasto, 96 visualizaciones, precio por visualización 1,04 Euros… ¡Por cada visualización! Esto, por si no os lo parece es carísimo. Calculemos que por cada 100 visualizaciones obtenemos 5cvs (1 de cada 20, esto es ser muy optimista), si de cada 10cvs obtenemos 1 al que entrevistar y que, de media, hay que entrevistar a 5 candidatos por puesto… Nos queda que necesitaríamos un mínimo de 5*10*20 = 1000 visualizaciones.

LinkedIn ¿me quieres decir que para contratar un programador (que tampoco busco un experto) tengo que gastarme 1.040 Euros?

A mi esto me ha parecido un error, y como tal se lo he preguntado a la amable gente de linkedin en twitter…

Qué majos! .. Vamos a ello…

Umm, no es ninguna de esas opciones, vamos a abrir incidencia

Vamos a ver que mi pregunta NO es sobre LinkedIn ADS, que de eso no tengo cuenta.. A ver si hay otra forma…

Pues no, no ayuda la verdad…

Y esto tampoco… ¿Cómo que las visitas disminuyen con el tiempo? Oye, que os habéis comido 100 pavos en dos días y solo me habéis dado 96 visualizaciones… Algo pasa

Y chin-pum ahí se acaba la interacción con la ayuda de linkedin… plasplasplas

Así que, si me preguntáis a mi, LinkedIn ha dejado de ser un sitio asequible para poner anuncios de trabajo…