Quantcast
Channel: Planeta Código
Viewing all 2699 articles
Browse latest View live

Blog Bitix: Análisis y guía del juego de estrategia Frostpunk

$
0
0

Frostpunk ha sido uno de los juegos con los que he disfrutado mucho de los pocos que he jugado hasta el momento en la Playstation 4. Su historia diferente y el tener que tener que tomar decisiones difíciles para conseguir la supervivencia de la colonia lo hacen distinto a los muchos otros juegos disponibles. No es muy largo pero acabado activa nuevos modos de juego para seguir jugándolo.

Los juegos de estrategia no suelen abundar mucho en las consolas, el uso del mando no es lo ideal para este tipo de juegos al igual que ocurre en otros que son mejores con teclado y ratón. Pero hay algunos buenos juegos de estrategia, uno de ellos es Frostpunk de 11 Bit Studios.

La historia de Frostpunk es diferente a lo habitual, está basado en el acontecimiento de un cataclismo apocalíptico en una época alternativa pasada que ha hecho que las temperaturas hayan descendido significativamente hasta llegar al punto de congelación para el desarrollo de la vida tal y como la ha conocido la humanidad hasta ese momento. La humanidad se ha reducido a un grupo de humanos que ha de sobrevivir construyendo una nueva colonia alrededor de un generador alimentado con carbón que proporciona el calor para no perecer congelados. Se trata de un juego de construcción de ciudades, gestión de recursos y supervivencia con un árbol de investigaciones tecnológicas y leyes que proporcionan mejoras.

No es un juego complicado pero requiere plantear bien las prioridades y construcciones para conseguir llegar al final dado que como en este tipo de juegos los recursos son limitados o de lo contrario los colonos se rebelarán finalizando la partida con la expulsión del jefe de la colonia al que representamos en el juego.

Pantalla inicialPantalla inicialMenú

Pantalla inicial y menú

Frostpunk es un juego corto sabiendo cual es la estrategia para sobrevivir. En mi caso me ha gustado mucho y me he divertido bastante con él tomando las decisiones que finalmente me han permitido superar con éxito el juego. Una vez acabada el modo historia inicial se habilitan otros modos de juego que permiten rejugarlo durante más tiempo. Más recientemente también se ha publicado una expansión del juego Frostpunk The last Autumn ambientada en un punto anterior en la línea temporal de Frostpunk que permite conocer más detalles de esta historia.

Ha sido lanzado para PC y consolas, yo lo he jugado en la PlayStation 4. Los textos están en español pero los diálogos están en inglés. Es un juego del 2019 en consolas con lo que hasta pasado un tiempo no tendrá una oferta importante y de forma habitual, en uno de estos momentos se puede comprar por unos 20€ en la PlayStation Store o físico en Amazon.

Anticipación del juego

Este artículo contiene información detallada de como completar con éxito el juego, parte de la diversión de un juego es descubrir por uno mismo una estrategia propia que permita superar los retos que se plantean.

Sin embargo, algunos son difíciles sin una pequeña ayuda que obliga a tener que recomenzarlos. Este artículo contiene información detallada sobre las partes importantes para hacer más fácil el terminar el juego.

Estrategia inicial

Frostpunk es un juego de gestión de recursos en el que hay que ser previsor a las necesidades futuras para no malgastar tiempo esperando a tener los recursos necesarios. Hay que construir edificios por adelantado antes de que sean imprescindibles o acumular recursos para acometer la siguiente investigación en cuanto se pueda. De forma regular es aconsejable realizar guardados para poder volver a un punto anterior para poder reconducir la partida tomando otras decisiones.

Los primeros momentos son los más difíciles ya que los recursos son escasos tanto en materias primas como trabajadores e ingenieros. El primer objetivo es usar los trabajadores e ingenieros para conseguir los mínimos recursos que permitan construir los primeros edificios. Los recursos son carbón para alimentar el generador, madera y acero para las construcciones. Por otro, conseguir comida con puestos de cazadores.

También hay que proporcionar una casa y atención médica a todos los colonos, de lo contrario aumentará el descontento y la esperanza. Por lo que hay que construir casas para todos los ciudadanos, uno o dos puestos médicos y un comedor. La forma de construir las casas es aconsejable construirlas agrupadas en un mismo sector del núcleo y dejando algunos huecos ya que avanzando el juego algunos edificios afectan a los habitantes cercanos de esas construcciones. Algunos edificios no es necesario que estén cerca del generador como los depósitos pero las cas de los colonos si, el espacio alrededor del generador es limitado por lo que hay que aprovecharlo para los edificios que sean necesario que tengan calor.

InicioInicioInicio

InicioInicioInicio

Inicio

Inicio

En el transcurso del juego los colonos realizarán algunas peticiones en las que podremos optar por varias respuestas, hacerles caso o ignorarlos. Dependiendo de la decisión habrá que construir algún edificio y dependiendo del cumplimiento de la promesa aumentará el descontento o bajará la esperanza. Aunque la decisión sea difícil no siempre hay que hacer atender a sus peticiones ya que los recursos son escasos.

La firma de leyes permite establecer políticas que proporcionan algunas ventajas como poder usar niños en algunas tareas. Son un árbol de desarrollo. Algunas son establecer turnos de trabajo nocturnos, proporcionar sopa en vez de raciones completas, construir un nevero para los colonos que perezcan o mejorar las atenciones médicas. Cada vez que se firma una ley hay que esperar un tiempo hasta poder firmar la siguiente, es aconsejable que cada vez que se pueda inmediatamente firmar la siguiente que proporcione la mayor ventaja que se considere sin embargo hay que tener en cuenta que algunas requieren construir algún edificio en un determinado tiempo, un día o dos, de modo que hay que tener preparados los recursos necesarios para poder construir esos edificios.

El otro árbol de desarrollo son las investigaciones proporcionadas por los talleres. Estos proporciona mejoras tecnológicas de caza, de poder construir nuevos edificios, avances para hacer más eficientes a los trabajadores, minas, construir autómatas o mejorar el generador. Inicialmente las más interesantes serán las dedicadas conseguir recursos. Los avances tecnológicos se dividen en niveles, no hace falta desarrollar todos los de un nivel siguiente pero cada nivel ha de ser investigado para tener acceso él.

En la fase inicial también será necesario construir un puesto de investigación para explorar los alrededores que proporcionarán detalles de la historia, conseguir recursos y nuevos colonos. Hay diferentes construcciones entre las que están las dedicadas a la gente como casas y que mejoran la esperanza, salud como puestos médicos y hospitales, los dedicados a recursos como comida y materias primas como carbón, madera y acero, finalmente los dedicados a tecnología como los talleres, factoría y calefactores.

Estrategia juego medio

Una vez asegurada la obtención de recursos imprescindibles en la fase de juego medio los objetivos son mantener el descontento en niveles bajos y la esperanza en niveles altos de lo contrario será la causa de finalización del juego.

En esta fase los exploradores encontrarán nuevos colonos y proporcionará más trabajadores así como depósitos externos que proporcionan materias, una de ellas será la de los núcleos de vapor que permite construir autómatas en la factoría que los usan como recurso. Los autómatas permiten no tener que usar trabajadores o ingenieros en los edificios además de que son capaces de trabajar todo el día en vez de solo las horas de trabajo como los colonos y no les afectan las bajas temperaturas de las tormentas.

Dependiendo de las necesidades hay otros recursos que se consiguen con depósitos externos carbón, madera o acero hay que elegir uno de ellos ya que solo es posible construir dos depósitos externos y los núcleos de vapor solo es posible conseguirlos con uno de ellos y los autómatas son interesantes para emplearlos en las minas y edificios para conseguir recursos. Las exploraciones permite obtener más colonos pero hay que ser previsor y construir por adelantado las casas que sean necesarias para albergarlos o tener siempre algunas casas sobrantes más de las necesarias.

Algunos edificios que permiten tener controlado los niveles de descontento bajos y la esperanza alta son las zonas de peleas, las iglesias, la taberna y el importante templo con los custodios de la fe en la rama de propósito. Se tiene acceso a estos edificios promulgando sus respectivas leyes. En el árbol de leyes en un determinado momento se ha de optar por el árbol de la fe y esperanza o del orden que da acceso a un nuevo árbol de leyes.

Árbol de tecnologíasÁrbol de tecnologíasÁrbol de tecnologías

Árbol de tecnologíasÁrbol de tecnologíasÁrbol de tecnologías

Árbol de tecnologíasÁrbol de tecnologíasÁrbol de tecnologías

Árbol de tecnologíasÁrbol de tecnologíasÁrbol de tecnologías

Árbol de tecnologías

Árbol de leyesÁrbol de leyesÁrbol de leyes

Árbol de leyes

En esa fase el objetivo es acumular recursos sobre todo carbón y comida para hacer frente a la tormenta del final. Será necesario construir depósitos grandes para tener capacidad para acumularlos. También es aconsejable los cuatro talleres que se pueden construir para realizar las investigaciones más rápido, y estar continuamente tiendo alguna investigación en marcha incluso teniendo que realizar turnos nocturnos. El uso de estos turnos nocturnos aumentarán el descontento que se mantendrá controlador con las iglesias, tabernas y templo.

La comida se consigue de dos formas con los cazadores o con los invernaderos. En mi opinión es mejor construir puestos de cazadores ya que estos permiten conseguir niveles de comida parecidos que los invernaderos pero no requieren emplear núcleos de vapor para construir los edificios que están mejor empleados para construir autómatas. Será necesario construir unos 5 o 6 puestos de cazadores.

Las minas de carbón, de acero y perforadoras permiten acceder a recursos en cantidades que podrían considerarse ilimitados de modo que es necesario construir estos edificios y sus respectivos avances con mayor eficiencia y poner en ellos autómatas también investigando sus mejoras para hacerlos más eficientes. Se pueden construir hasta tres minas de carbón, dos perforadoras para conseguir madera y dos minas de acero con lo que son necesarios unos siete autómatas. Alguno más si se quieren para algún puesto médico pero no son imprescindibles para estas tareas.

También será necesario realizar alguna investigación para las mejoras del generador y calderas de vapor para que afecte a áreas más alejadas de núcleo, con más eficiencia para soportar alguna tormenta que baja las temperaturas de modo que las casas soporten el frío. Hay que investigar las mejoras que den acceso a poder construir barracones y casas con mejores aislamientos y modernizar progresivamente los hogares a casas y las minas a minas avanzadas.

Algunas decisiones difícilesAlgunas decisiones difíciles

Algunas decisiones difíciles

Estrategia juego final

El juego final consiste en una tormenta que dura una semana y en la que hay que disponer del suficiente carbón y comida acumulada en los depósitos grandes. Ya que en la tormenta final los puestos de cazadores no pueden salir a obtener comida y en los peores momentos de la tormenta los trabajadores dejarán sus puestos de trabajo. Tener autómatas permite seguir pudiendo conseguir carbón.

Dado que el generador a máximo rendimiento consume carbón es necesario tener carbón acumulado. Con los recursos acumulados es sencillo soportar la tormenta final. En los peores momentos de la misma será necesario activar la opción de sobrerendimiento del generador cuando se observe que las casas tienen el icono de congelación, hay que vigilar la presión del generador para que no llegue al máximo o de lo contrario explotará siendo esta otra forma de fracaso en el juego.

Durante las exploraciones habrá que tomar la decisión de dejar abandonados a algunos colonos en vez de acogerlos en la colonia dado que no hay casas, comida o recursos para todos los colonos, un objetivo del juego puede ser intentar salvar a los máximos colonos que se pueda.

Superviviencia

Superviviencia

Nuevos modos de juego

Al finalizar el modo historia se habilitan otros modos de juego y escenarios con otras formas de supervivencia que le dan al juego mas rejugabilidad.

EscenariosEscenario Nuevo hogar, historia principal

Escenarios

Escenario Las arcasEscenario RefugiadosEscenario La caída de invernia

Modo infinito

Frostpunk Wiki

En la Wiki de Frostpunk de Fandom están recogidos con detalle de los construcciones, recursos, tecnologías, leyes y escenarios. Esta información resulta muy útil para elegir la que consideremos la mejor estrategia o revisar si la que utilizamos no es del todo efectiva.

Banda sonora original


Variable not found: Enlaces interesantes 403

$
0
0
Enlaces interesantesCuando una petición retorna un código de estado HTTP 403 (Forbidden), quiere decir que ésta fue realizada correctamente, pero el cliente no está autorizado para acceder al recurso o servicio que se intenta utilizar. Quizás porque la petición no incluyó las credenciales correctas, o tal vez porque eran insuficientes para acceder a él, pero la petición no debe ser repetida porque el resultado será el mismo.

A veces se confunde con el HTTP 401, pero son muy diferentes:
  • HTTP 401 (Unauthorized) indica, a pesar de su nombre, un problema de autenticación, y debe evaluarse antes de decidir si el usuario tiene acceso o no al recurso concreto.
  • HTTP 403 (Forbidden) indica un problema de autorización, y es más específico que el anterior porque indica que el servidor sabe quién es el cliente y conoce el recurso al que intenta acceder, pero decide que no está autorizado a hacerlo.
Y dicho esto, vamos a por nuestra ración de enlaces que, como es habitual, espero que os resulten interesantes :)

Por si te lo perdiste...

  • Hace unos días me entrevistaron en la Resistencia Tecnológica, el divertido programa de Crossdvlup guiado por Alberto Díaz (@adiazcan), David Vidal (@D_Vid_45) y Sergio Hernández (@shmancebo). Algo más de hora y media charlando sobre la vida, el blog, ASP.NET, Blazor y algunas otras cosillas, que podéis ver en Youtube.
    Aparte, os recomiendo suscribiros al canal y echar un vistazo a los programas anteriores, porque podréis encontrar temas muy interesantes y personajes ilustres :)

.NET Core / .NET

ASP.NET Core / ASP.NET

Azure / Cloud

Conceptos / Patrones / Buenas prácticas

Data

Machine learning / IA / Bots

Web / HTML / CSS / Javascript

Visual Studio / Complementos / Herramientas

Xamarin

Otros

Publicado en Variable not found.

Variable not found: Cómo mostrar el número de usuarios conectados a una aplicación Blazor Server, en tiempo real

$
0
0
BlazorEn Blazor Server, cada usuario que esté utilizando la aplicación establece una conexión SignalR para enviar al servidor sus interacciones con la página, así como para retornar de vuelta al usuario las modificaciones del DOM realizadas desde el servidor. Esta conexión, junto con la información del estado del cliente almacenada en el servidor, es lo que en Blazor Server se denomina un "circuito".

Y ya que el servidor es consciente en todo momento de los usuarios conectados, en teoría debería ser posible contarlos para, por ejemplo, mostrarlos en pantalla como en la siguiente captura:

Aplicación Blazor mostrando el número de usuarios conectados

En este post vamos a ver cómo conseguir precisamente eso: incluir en las páginas del proyecto un contador de usuarios conectados que irá actualizándose en tiempo real, para, por el camino, profundizar un poco en el ciclo de vida de los circuitos de Blazor Server.

1. El servicio contador de usuarios

Antes de profundizar en las particularidades de Blazor Server, vamos a implementar un servicio bastante sencillito, que nos ayudará a mantener en memoria el contador de usuarios conectados y nos ofrecerá un par de métodos para gestionar los cambios.

El código, como se puede comprobar, habla por sí mismo:
public class UserCountService
{
public event EventHandler<int> OnChanged;
private int _counter = 0;
public int CurrentUsersCount => _counter;

public void Increment()
{
Interlocked.Increment(ref _counter);
OnChanged?.Invoke(this, _counter);
}

public void Decrement()
{
Interlocked.Decrement(ref _counter);
OnChanged?.Invoke(this, _counter);
}
}
No hay nada más allá de lo normal, aunque quizás lo que más os llame la atención la definición del evento OnChanged que utilizamos para notificar a los consumidores de este servicio de que se han producido cambios en el número de usuarios conectados. Más adelante veremos por qué es necesario esto.

Este servicio deberíamos registrarlo en el método ConfigureServices() como Singleton, pues sólo necesitaremos una instancia compartida durante todo el tiempo de vida de la aplicación:
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<UserCountService>()
... // More service registrations here
}

2. ¿Cómo nos enteramos cuando un usuario conecta o desconecta?

Blazor permite introducir lógica personalizada en el ciclo de vida de los circuitos, gracias a la abstracción CircuitHandler. Esta clase abstracta define cuatro métodos que permiten tomar el control cuando:
  • OnCircuitOpenedAsync(): invocado cuando nuevo circuito es creado
  • OnConnectionUpAsync(): cuando la conexión ha sido establecida o restablecida
  • OnConnectionDownAsync(): la conexión con un cliente se cerró
  • OnCircuitClosedAsync(): notifica que el circuito ha sido eliminado
En nuestro caso, simplemente heredaremos de CircuitHandler e implementaremos OnCircuitOpenedAsync() y OnCircuitClosedAsync() para incrementar y decrementar, respectivamente, el contador de usuarios conectados, utilizando para ello el servicio que hemos creado algo más arriba:
public class UserCountCircuitHandler: CircuitHandler
{
private readonly UserCountService _userCountService;

public UserCountCircuitHandler(UserCountService userCountService)
{
_userCountService = userCountService;
}

public override Task OnCircuitOpenedAsync(Circuit circuit, CancellationToken cancellationToken)
{
_userCountService.Increment();
return base.OnCircuitOpenedAsync(circuit, cancellationToken);
}

public override Task OnCircuitClosedAsync(Circuit circuit, CancellationToken cancellationToken)
{
_userCountService.Decrement();
return base.OnCircuitClosedAsync(circuit, cancellationToken);
}
}
Para hacer que Blazor Server conozca la existencia de nuestra clase UserCountCircuitHandler es neceario registrarla en el inyector de dependencias asociada a la clase abstracta CircuitHandler, de nuevo como Singleton porque sólo necesitaremos una instancia:
services.AddSingleton<CircuitHandler, UserCountCircuitHandler>();
Durante los cambios de estado del circuito, Blazor Server invocará los métodos correspondientes en todas las clases registradas como CircuitHandler.

Con lo que hemos desarrollado hasta este momento, nuestra aplicación Blazor Server ya irá registrando las aperturas y cierres de circuitos, manteniendo el contador de usuarios sincronizado. Veamos ahora cómo mostrar esta información y actualizarla en tiempo real sobre la página.

3. ¿Cómo mostramos los usuarios conectados?

Sin duda, lo más sencillo es crear un componente Blazor reutilizable que muestre en todo momento del valor de la propiedad CurrentUsersCount del servicio UserCountService, algo como lo siguiente:
@* File: UserCount.razor *@
@inject UserCountService UserCountService

<span @attributes="Attributes">
@UserCountService.CurrentUsersCount
</span>

@code {

[Parameter(CaptureUnmatchedValues = true)]
public Dictionary<string, object> Attributes { get; set; }
}
Observad que estamos utilizando CaptureUnmatchedValues en el parámetro Attributes, con objeto de expandir estos atributos en la etiqueta <span>. Puedes leer más sobre ello en el post "Capturar todos los parámetros enviados a un componente Blazor".
De esta forma, podríamos utilizarlo desde cualquier componente de la siguiente forma:
<UserCount style="font-weight: bold" />
Sin probamos el código anterior, veremos que funcionará bien... al menos la primera vez. Si abrimos varias ventanas, podremos comprobar que este valor no se va modificando en tiempo real conforme se vayan abriendo nuevos circuitos.

Pero si lo pensamos, tiene su lógica: UserCountService.CurrentUsersCount es modificado de forma asíncrona por otros hilos cuando otros circuitos cambian su estado, y la interfaz de usuario no es notificada para que actualice el valor. Por tanto, el contador que veremos siempre en pantalla será el valor inicial del contador en el momento de cargar el componente.

4. Actualizar los usuarios conectados en tiempo real

¿Y cómo podemos notificar a la interfaz de usuario que el valor ha cambiado? Pues aquí es donde entra en juego el evento OnChanged que recordaréis que habíamos declarado en UserCountService y que lanzábamos cada vez que el contador era modificado:
public class UserCountService
{
public event EventHandler<int> OnChanged;
...
public void Increment()
{
...
OnChanged?.Invoke(this, _counter);
}

public void Decrement()
{
...
OnChanged?.Invoke(this, _counter);
}
}
Para ser notificado de los cambios, el componente UserCount.razor debe suscribirse a este evento, y utilizarlo para refrescar la interfaz. El siguiente código muestra el código ya completo, y lo comentamos justo abajo:
@* File: UserCount.razor *@
@implements IDisposable
@inject UserCountService UserCountService

<span @attributes="Attributes">
@UserCountService.CurrentCount
</span>

@code {

[Parameter(CaptureUnmatchedValues = true)]
public Dictionary<string, object> Attributes { get; set; }

protected override void OnInitialized()
{
UserCountService.OnChanged += UpdateCounter;
base.OnInitialized();
}

private async void UpdateCounter(object sender, int counter)
{
await InvokeAsync(StateHasChanged);
}

public void Dispose()
{
UserCountService.OnChanged -= UpdateCounter;
}
}
Lo primero a tener en cuenta, es que en OnInitialized() nos suscribimos al evento, pero debemos desuscribirnos cuando éste sea eliminado para evitar fugas de memoria. Para ello, hacemos que implemente IDisposable usando la directiva @implements, y utilizamos Dispose() para eliminar la suscripción.

Por otra parte, observaréis que hemos implementado en UpdateCounter() el handler del evento lanzado cuando se producen cambios. En su interior, vemos que mediante InvokeAsync() aseguramos que el contexto de sincronización de Blazor, y en él ejecutamos StateHasChanged() para notificar al componente que su estado cambió, por lo que debe refrescar la interfaz.

¡Y eso es todo! Una vez unidas las piezas ya tendremos nuestro flamante componente <UserCount> capaz de mostrar en tiempo real el número de usuarios conectados a nuestra aplicación Blazor Server.

Blazor counter en acción

Publicado en Variable not found.

Picando Código: Paquete para Emacs: helm-treemacs-icons

$
0
0

Hace un tiempo me encontré con este paquete para Emacs que me resultó sumamente útil. Integra helm, el sistema que uso para cambiar de buffers o archivos, con treemacs (y treemacs-icons), el sistema que muestra íconos en el árbol de archivos de un proyecto. De esta forma, podemos ver los íconos de los archivos cuando estamos usando helm para cambiar de buffer. Esto hace mucho más práctico el cambio de buffers y la navegación de archivos. Al tener un ícono que representa el tipo de archivo, y el cerebro va aprendiendo a identificar los íconos, me viene resultando todavía más rápido encontrar por tipos de archivo (generalmente mantengo sesiones de Emacs por muchos días y a veces hasta cientos de buffers y archivos abiertos). Sumado a que helm permite ir filtrando por texto, es una forma súper práctica de cambiar de uno a otro.

Lo pueden encontrar en GitHub: yyoncho/helm-treemacs-icons.

helm-treemacs-icons

Por ahora, para usar el paquete hay que instalarlo manualmente. Pero el README promete instalación con Melpa próximamente. Las instrucciones son: asegurarse que tengamos helm y treemacs instalados, clonar el proyecto y agregarlo al path de Emacs. En mi caso estoy usando Spacemacs, y lo agregué así:

(load-file "~/.emacs.d/private/helm-treemacs-icons/helm-treemacs-icons.el")
(require 'helm-treemacs-icons)
(helm-treemacs-icons-enable)

Creo que este mismo código debería funcionar en cualquier configuración de Emacs, siempre y cuando definamos bien el path de dónde cargar el archivo helm-treemacs-icons.el.

Le pregunté al desarrollador cómo agregarlo como capa a Spacemacs, y me respondió que tiene pensado agregarlo a la capa treemacs, algo que me parece una buena idea. Así que posiblemente lo veamos como parte de treemacs en algún momento.

Hubo un Pull Request inicial a melpa para agregar este paquete. Pero el autor lo cerró comentando que renombraría el paquete a helm-icons y lo integratía con all-the-icons. Pero esto fue antes de las últimas actualizaciones. Mientras tanto, funciona bastante bien y resulta súper práctico, así que seguiré atento a su desarrollo.

Blog Bitix: Introducción y uso básico de la distribución GNU/Linux Fedora Silverblue

$
0
0

Fedora Silbervlue es una distribución innovadora es su forma de sistema base usando OSTree e instalar aplicaciones gráficas con Flatpak y de paquetes de linea de comandos con Toolbox. Todas estas tecnologías le permiten considerarse una distribución rolling-release tanto en el sistema como aplicaciones y paquetes. Estas tecnologias y forma de actualizar el sistema hace que sea mucho menos propenso a errores que los tradicionales en las distribuciones GNU/Linux de actualización de paquetes, ¿la siguiente generación de distribuciones serán como Fedora Silverblue?.

Distribuciones GNU/Linux hay muchas con diferencias en algunos aspectos, el más cercano al usuario es entorno de escritorio entre los más populares GNOME, KDE, XFCE, MATE o Cinnamon entre otros pero hay otros aspectos relevantes entre ellos el gestor de paquetes que utiliza, el modelo de actualización, en que otra distribución está basada, cual es su periodo de publicación de nuevas versiones, su popularidad, tiempo de vida o si está respaldada por una empresa.

A pesar de estas diferencias la mayoría de las distribuciones para los usuarios son parecidas en muchos aspectos. Tradicionalmente cada distribución tiene su repositorio de paquetes y su comando gestor de paquetes con el que es posible instalar y desinstalar paquetes. La mayoría usa systemd como sistema de inicio para controlar los procesos y servicios. El entorno de escritorio GNOME o KDE es el mismo en cada distribución si no se tiene en cuenta que las versiones puedan ser diferentes.

Las distribuciones GNU/Linux han cambiado en algunos aspectos importantes como la sustitución del sistema de inicio de SysV a systemd o cambiado el servidor gráfico Xorg por Wayland y van a hacerlo más en el futuro con el nuevo sistema para crear VPNs con WireGuard o el sistema multimedia para sonido y vídeo PipeWire.

En mi caso utilizo Arch Linux desde hace ya casi una década y estoy contento con ella. Los motivos que tengo para preferir esta distribución son su modelo de actualizaciones rolling-release en el que cada actualización todos los paquetes se actualizan a la última versión, su gestor de paquetes pacman que es muy rápido, los paquetes tiene pocas modificaciones realizadas por los mantenedores, es altamente personalizable y también no menos importante casi como todo lo anterior su documentación wiki con información muy útil para cualquier usuario de GNU/Linux.

Arch Linux es una de las distribuciones más populares pero no proporciona ningún asistente automatizado de instalación sino que después de arrancar el medio de inicio hay que introducir los comandos manualmente uno a uno hasta completar la instalación. Esto la hace difícil para los usuarios recién llegados a GNU/Linux o para los usuarios que no desean invertir tiempo en conocer cómo instalarla. También incluso para los usuarios expertos es que ya conocen como instalarla pero que el hecho de hacerlo manualmente es un tiempo que a veces no se dispone además de repetitivo.

Por esos motivos creé un script de instalación de Arch Linux completamente automatizado y desatendido con cierto grado de personalización en las opciones más comunes, es un simple script bash con todos los comandos que componen el proceso de instalación y que simplemente revisarlo sirve como documentación que además si se desea se puede ejecutar.

Pero a pesar de todo Arch Linux se basa en los principios básicos de los que hasta hoy han estado basadas las distribuciones. Gestor de paquetes, repositorio de paquetes y actualizaciones frágiles. Es muy posible que las distribuciones cambien tal y como las hemos conocido hasta ahora, ya se está produciendo cambios con Flatpak como sistema de instalar aplicaciones independientemente de la distribución y mantenidos por los propios desarrolladores del software y no los mantenedores de la distribución.

Una distribución que se basa en principios diferentes que pueden ser el futuro próximo es Fedora Silverblue.

Fedora Silverblue

Fedora Silverblue

La distribución Fedora Silverblue

Una de las mayores fuentes de problemas de las distribuciones y de los sistemas operativos son las actualizaciones que por los cambios que introducen con nuevas versiones del software en ocasiones hace que algunas partes dejen de funcionar. Son solucionables desactualizando un paquete o en los casos más graves hace que el sistema ni siquiera se inicie correctamente llegando incluso a tener que reinstalar el sistema o peor aún provocando pédida de datos.

Otro problema es que algunas distribuciones tienen como principio la estabilidad del software y dado que las nuevas versiones de los programas son una fuente de inestabilidades optan por únicamente proporciona actualizaciones para errores de seguridad. Esto proporciona una mayor estabilidad pero hace que los programas no estén actualizados a las últimas versiones con lo que no se benefician de mejoras en nuevas características, mejoras de soporte de hardware, de rendimiento o incluso de seguridad.

Fedora Silverblue adopta varios principios para solucionar esos problemas. Uno es utilizar una base inmutable igual para todos los sistemas en los que se instala de modo que no haya diferencias ni errores por variaciones en el software del sistema. Es posible volver a una versión anterior en caso de algún error de modo que el sistema nunca quede completamente roto. Las aplicaciones de usuario y paquetes se instalan independientemente del sistema base inmutable lo que hace que no afecten a la estabilidad del sistema.

Fedora SilverblueFedora SilverblueFedora Silverblue

Fedora Silverblue

Las tecnologías que permiten adoptar esos principios a Fedora Silverblue son OSTree para el sistema base inmutable, Flatpak para las aplicaciones de usuario gráficas y Toolbox para instalar software de línea de comandos en contenedores.

OSTree es un proyecto que combina un modelo parecido a git para establecer y descargar árboles de sistemas de archivos de arranque, junto con una capa para disponerlos y gestionarlos con la configuración de arranque. OSTree es usado por rmp-ostree, un sistema híbrido de paquete e imágenes que usa Silverblue. Replica de forma atómica un sistema operativo base que permite al usuario añadir capas de paquetes RPM tradicionales encima del sistema base si se necesita.

Instalación

La instalación se realiza con un asistente gráfico después de haber descargado el medio de instalación y haberlo grabado en una memoria USB para inciar el sistema con él. Es necesario poco más que seleccionar la distribución del teclado, el particionado y la clave del superusuario root para realizar la instalación.

Instalación de Fedora SilverblueInstalación de Fedora SilverblueInstalación de Fedora Silverblue

Instalación de Fedora SilverblueInstalación de Fedora SilverblueInstalación de Fedora Silverblue

Instalación de Fedora Silverblue

Instalación de Fedora Silverblue

Primer inicio

Al iniciar el sistema por primera vez un nuevo asistente permite crear la cuenta de usuario compuesto de nombre y contraseña con la que iniciar sesión en el sistema.

Primer inicioPrimer inicioPrimer inicio

Primer inicioPrimer inicioPrimer inicio

Primer inicio

Primer inicio

Al usar GNOME como entorno de escritorio no se diferencia a cualquier otro sistema con GNOME. La mayor diferencia está en que las aplicaciones preinstaladas son muy pocas, reduciéndose a las básicas como el navegador Firefox, la terminal, el explorador de archivos y editor de texto. Este permite al usuario tener instaladas únicamente las aplicaciones que desee o no tener que desinstalar las aplicaciones que no desea. Las aplicaciones que se deseen se deben instalar con Flatpak.

Administración del sistema, actualización

El software que compone el sistema base se puede actualizar, los siguientes comandos permiten conocer cuales son las actualizaciones disponibles. Las actualizaciones están integradas con el programa Software de GNOME que muestra notificaciones cuando hay alguna actualización disponible.

Pero también puede realizarse desde la línea de comandos. El siguiente comando realiza la operación de actualización.

1
$ rpm-ostree upgrade
rpm-ostree-upgrade.sh

Para simplemente comprobar que actualizaciones hay disponibles sin instalarlas.

1
2
$ rmp-ostree status
$ rpm-ostree upgrade --check
rpm-ostree-status.sh

Para actualizar entre versiones mayores, de la 32 a posteriores, de Foedora Silverblue se utilizan los siguientes comandos en los que cambiará el número de la versión.

1
2
3
$ ostree remote list
$ sudo ostree remote gpg-import fedora -k /etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-32-primary
$ rpm-ostree rebase fedora:fedora/32/x86_64/silverblue
rpm-ostree-rebase.sh

La mayoría del software de usuario se instala con Flatpak y Toolbox siendo la forma recomendada de hacerlo. Sin embargo, algunos programas ha de instalarse modificando la instalación de Silverblue utilizando package layering, como un intérprete de comandos distinto a bash. La mayoría de paquetes RMP es posible instalarlos, aún así este método debe usarse en casos excepcionales que no sea posible hacerlo con Flatpak o Toolbox ya que podría comprometer la estabilidad del sistema.

1
$ rpm-ostree install <package name>
rpm-ostree-install.sh

ActualizaciónActualizaciónActualización

Actualización

En caso de que una actualización produzca algún error se puede volver a la versión anterior con el siguiente comando.

1
$ rpm-ostree rollback
rpm-ostree-rollback.sh

Instalación de programas gráficos

Las aplicaciones de usuario gráficas se instalan con Flatpak y en el caso de GNOME con la aplicación Software. A medida que pasa el tiempo hay más programas disponibles en esta forma de distribuir software y muchos de los programas más comunes está disponibles como la colección ofimática LibreOffice, el reproductor multimedia VLC, el editor de texto avanzado Visual Studio Code o el entorno de desarrollo integrado IntelliJ.

Con la aplicación de software es posible encontrar todo este software, instalarlo y desinstalarlo con un clic en un botón. Lo único necesario es añadir el repositorio Flathub como fuente de programas.

Repositorio FlathubRepositorio Flathub

Repositorio Flathub

Instalación de softwareInstalación de softwareInstalación de software

Instalación de software

Instalación de software

Dos programas instalados como paquetes Flatpak.

Intellij IDEAVisual Studio Code

Programas instalados como Flatpak

También es posible instalar el paquetes Flatpak desde la linea de comandos.

Uso de Toolbox, programas de línea de comandos en contenedores

El resto de paquetes de línea de comandos se pueden instalar en contenedores con Toolbox basados en podman que es una alternativa compatible de Docker. Lo especial de estos contenedores es que tiene acceso a la carpeta personal o directorio home del usuario de modo que pueden crear archivos o modificar los existentes en esta ubicación.

Destro de estos componentes se instalan los paquetes con el gestor de paquetes dnf.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
$ toolbox run dnf search openjdk
Last metadata expiration check: 5 days, 18:10:47 ago on Sun May 10 00:09:19 2020.
======================= Name & Summary Matched: openjdk========================
java-11-openjdk-demo.x86_64 : OpenJDK Demos 11
java-1.8.0-openjdk-demo.x86_64 : OpenJDK Demos 8
java-latest-openjdk-demo.x86_64 : OpenJDK Demos 14
java-11-openjdk-jmods.x86_64 : JMods for OpenJDK 11
java-11-openjdk-src.x86_64 : OpenJDK Source Bundle 11
java-11-openjdk.x86_64 : OpenJDK Runtime Environment 11
java-11-openjdk.i686 : OpenJDK Runtime Environment 11
java-latest-openjdk-jmods.x86_64 : JMods for OpenJDK 14
java-1.8.0-openjdk-src.x86_64 : OpenJDK Source Bundle 8
java-latest-openjdk-src.x86_64 : OpenJDK Source Bundle 14
....

$ sudo dnf install java-11-openjdk.x86_64
$ java -version
toolbox-package-install.sh

Instalación de programas de línea de comandosInstalación de programas de línea de comandosInstalación de programas de línea de comandos

Instalación de programas de línea de comandos

Para no modificar el sistema base de Silverblue otra forma de instalar Java es con la utilidad sdkman que además permite cambiar entre versiones fácilmente y tener acceso a diferentes implementaciones del JDK, entre otras utilidades instalables con esta herramienta.

1
2
$ sdk list java
$ sdk install java 11.0.7-open
sdk-usage.sh

Conclusión

Si tuviese que probar o usar otra distribución diferente Arch Linux probablemente la que elegiría sería Fedora Silverblue por los principios innovadores en las que está basada que proporcionan varias mejoras en puntos importantes sobre las distribuciones como las hemos conocido tradicionalmente. Igualmente permite tener el software actualizado, es también rolling-release y mejora la fiabilidad de las actualizaciones.

En estos vídeos se proporciona una introducción sobre esta distribución que quizá marque el camino de aquí en adelante para otras.

Blog Bitix: La controversia sobre el sistema de inicio systemd adoptado en GNU/Linux

$
0
0

systemd ya tiene una década de desarrollo, ha sido adoptado como sistema de inicio en las distribuciones GNU/Linux más importantes como Debian, Ubuntu, Fedora o Arch Linux y derivadas. Durante este tiempo ha recibido múltiples críticas en varios aspectos. Sigue evolucionando cambiando aspectos importantes de cómo han sido siempre las distribuciones, uno de los próximos es posible que sea systemd-homed con la intención de hacer portables y autocontenidos las carpetas de inicio de los usuarios.

systemd

Linux

El sistema de inicio y control de procesos systemd creado por Lennart Poettering ha reemplazado en la mayoría de distribuciones GNU/Linux al más antiguo sistema SysVinit. A systemd se le ha criticado en varios aspectos incluso algunas personas llegando a crear forks de distribuciones con el principio de no usar systemd.

Poettering escribió un artículo respondiendo a 30 de los mayores mitos sobre systemd. También hay opiniones contrarias a systemd, otra persona respondía con 13 de las mayores falacias acerca de systemd. Aún con las críticas en su recepción que se ha hecho a systemd es admirable la fuerza de voluntad y determinación de Lennart Poettering que un día se propuso hacer un sistema de inicio que sea usado en toda la base de distribuciones de Linux, es capaz de sobreponerse a no hacerlo y un día proporciona ese sistema de inicio que funciona siendo adoptado en la mayoría de distribuciones Linux.

Componentes de systemdJerarquía unificada del kernel Linux, cgroups y systemd

Componentes de systemd y jerarquía unificada del kernel Linux, cgroups y systemd

En un comentario de reddit el mantenedor de los script init para Arch Linux compartía varios puntos en los que systemd es mucho mejor que los scripts init. Hay que tener en cuenta que los sistemas modernos actuales son más complejos, dinámicos y asíncronos que lo eran en la época que se creó SysVinit. No es posible determinar cuando una pieza de hardware estará disponible por ejemplo con los medios extraíbles. Durante bastante tiempo, esto ha sido resuelto lanzando eventos y esperando a udev. Esto toma mucho tiempo sin haber garantía que todo el hardware está disponible. Hacer esto con scripts de shell puede ser muy complejo, lento y propenso a errores. Hay que reintentar todo tipos de operaciones en un bucle hasta tener éxito. La solución es un sistema que realice acciones basado en eventos, esta es una de las más importantes características de systemd.

Estos eran varios de los problemas de los scripts init:

  • Los scripts init son estúpidos. En su primera fase son una serie de pasos estáticos que son ejecutados en cada inicio sin casi posibilidad de ajustar el comportamiento. En su segunda fase los demonios son iniciados en orden lo que significa que cada script init es llamado en serie uno detrás de otro.
  • Las complejas tareas en los scriptsshell requieren lanzar muchos programas externos de ayuda. Esto hace las cosas lentas. systemd trata la mayoría de estas tareas en código C o mediante las librerías correctas. No llama a muchos programas externos para realizar sus tareas.
  • El proceso de inicio completo está serializado lo que también lo hace muy lento. systemd puede paralelizarlo y lo hace bastante bien.
  • No hay indicación de cuándo un cierto demonio ha sido iniciado. Cada script init tiene que implementar algún tipo de manejo de archivos PID o similar. La mayoría de los scripts init no lo hacían. systemd tiene una solución totalmente confiable basada en los cgroups de Linux.
  • Eran posibles condiciones de carrera entre demonios iniciados con reglas udev, activación de dbus y configuraciones manuales. Puede ocurrir que un demonio sea iniciado múltiples veces incluso simultáneamente, lo que ocasiona resultados inesperados (esto era un problema real con bluez). systemd proporciona una única instancia donde todos los demonios son manejados. Ahora ni udev ni dbus inician demonios, ahora le dicen a systemd que necesitan un demonio específico y systemd se preocupa de ello.
  • Falta de configurabilidad. Era imposible cambiar el comportamiento de los scripts init de una forma que sobreviviese a las actualizaciones del sistema. systemd proporciona buenos mecanismos con redefiniciones específicas para la máquina, elementos que estén presentes y ocultamiento.
  • Mantenimiento costoso. Adicionalmente a los problemas de diseño mencionados los scripts init también tenían un largo número de errores. Corregir esos errores era siempre complicado y tomaba tiempo que no siempre se disponían mantenedores. Delegar esta tarea a una comunidad más grande, en este caso a la comunidad de systemd, ha hecho las cosas mucho más fáciles para los mantenedores.

Aunque algunos de estos problemas pueden ser resueltos con algo de trabajo y algunos han sido resueltos por otros sistemas de inicio basados en SysV no hay ningún sistema que haya resuelto todos estos problemas y lo haya hecho de una manera confiable como lo ha hecho systemd. Lo que la mayoría de las críticas consideran bloat el mantenedor de Arch los considera una complejidad necesaria para resolver problemas complejos de una manera genérica. Se puede decir lo que se quiera de Poettering pero él se ha dado cuenta de cuáles eran los problemas del sistema de inicio y ha proporcionado una solución que funciona.

Las críticas que se le hace a systemd son:

  • Viola la filosofía de UNIX. La filosofía de UNIX es que cada programa debe tener un propósito específico, si es necesario crear varios programas uno por cada propósito. Se dice que systemd es un único binario que viola la filosofía UNIX, la realidad es que systemd se compone de múltiples binarios, pero están separados y modularizados. En su uso dependen unos de otros, no pueden usarse sin los otros y esta es la violación a la filosofía UNIX y por la que en este aspecto no se los considera modulares.
  • Está sobrecargado (bloated) y es monolítico. De nuevo systemd está compuesto de múltiples binarios no es un un único binario.
  • Tiene errores. Como todo software, en el caso de un sistema de inicio por su criticidad son más notables. Cualquier otro sistema de inicio no estaría exento de errores. Tiene manejo de errores que en vez de fallar y tumbar el sistema deja el sistema en un punto que al menos se puede reiniciar.
  • No es portable. systemd es específico de Linux ya que usa varias funcionalidades que no están presentes en otros sistemas, una de ellas cgroups para el manejo de procesos. Esto aísla al resto de plataformas como la familia de sistemas operativos BSD que no tiene esas funcionalidades pero al mismo tiempo esas plataformas son libres de usar el sistema de incio que deseen.

Algunas distribuciones no usan systemd o es opcional, dos notables son Gentoo y Alpine Linux que usan OpenRC. Otras alternativas son runit, procd y supervisor. La distribución Devuan que surgió como propósito principal no usar systemd abandera las distribuciones que no lo usan. En la wiki de Gentoo hay una compraración entre los diferentes sitemas de inicio.

De esa comparación destaco dos cosas de systemd:

  • Los archivos de configuración de los servicios son proporcionados preferiblemente por los desarrolladores de los servicios y no los mantenedores de cada distribución, liberando a los mantenedores de esas tareas y haciendo que las mejoras en un servicio no sea exclusivo de una distribución sino que todas se beneficien de él.
  • El formato de los archivos de configuración de los servicios es descriptivo, no codificado en un lenguaje de programación con un script bash.

Arragonán: Ideas para mejorar tus Historias de Usuario

$
0
0

Me parecía un valor seguro hacerme con Fifty Quick Ideas to Improve your User Stories de Gojko Adzic y David Evans. Venía siguiendo los artículos del blog de Gojko Adzic (de hecho algunas de esas ideas ya están desarrolladas ahí) a raíz de leer Specification By Example y además tenía buenas referencias del libro. Desde luego que no me defraudó.

Tal y cómo está escrito existe una idea por capítulo que contiene la descripción, los beneficios clave y algunas recetas sobre cómo llevarla a cabo; teniendo en algunos casos referencias a otros libros y artículos donde profundizar más sobre esa idea. El formato está genial para revisitar de vez en cuando alguna de las ideas y llevarlas al día a día.

Creo que quienes más partido le pueden sacar a este libro son las personas con roles tipo product manager/owner o que tengan influencia sobre cómo se gestiona el producto y los stakeholders en una organización. Pero es muy interesante para cualquiera que se dedique a la creación de productos de software con cierto recorrido profesional e interés en profundizar sobre la gestión de producto.

Y hablo de cierto recorrido profesional porque no es un libro introductorio donde expliquen qué son las historias de usuario, si es mejor una u otra plantilla y cosas así.

Mientras lo leía estuve marcando lo que me parecieron los principales puntos de cada idea y al terminarlo, como ejercicio de repaso, decidí empezar a traducir esos extractos. Me pareció que sería interesante compartirlo, así que pedí permiso a Gojko para hacerlo.

Estas ideas están agrupadas en cinco bloques:

  • Creando historias
  • Planificando con historias
  • Discutiendo historias
  • Partiendo historias
  • Gestionando la entrega iterativa

Creando historias

Cuenta historias, no las escribas

Usar historias de usuario implica un modelo completamente diferente, es definir requisitos de forma colaborativa.

No te preocupes demasiado por el formato de historia

Experimenta con el formato:

  • Nombra las historias rápido, añadiendo los detalles después.
  • Evita caer en escribir soluciones obvias.
  • Piensa en más de un stakeholder interesado en el ítem, esto abre opciones de partir la historia.
  • Utiliza imágenes en vez de palabras.
  • Haz una pregunta.

Describe un cambio de comportamiento

Las iniciativas que aportan valor producen cambios observables en la forma de trabajar de alguien. Capturar ese cambio de comportamiento hace una historia medible desde un punto de vista de negocio y eso simpre abre una buena discusión.

Describe un cambio del sistema

La descripción de la historia debería aclarar exactamente cómo cambia el sistema o las reglas de negocio del momento actual y en el que la historia esté implementada. También necesitamos saber cuánto difiere del comportamiento actual. Empieza la discusión añadiendo otra cláusula a la plantilla de las historias (“Where as…”, “Instead of…”), debería aclarar lo más posible el contraste de lo que hay con lo que es necesario.

Enfoca las historias como experimentos que sobreviven

Las preguntas clave para el tamaño de la historia no deberían ser sobre la duración de la iteración, sino acerca de cuánto quieren invertir los stakeholders de negocio en saber si el cambio propuesto retornará lo que asumieron invertir. Enfocando las historias como experimentos podemos cambiar el enfoque desde la complejidad técnica hacia los outcomes (o resultados esperados) y el aprendizaje.

Diseña experimentos en torno a suposiciones y conviértelos en historias de usuario.

Cuidado con los roles genéricos

Evita “As an user…” como la peste. Una descripción clara y precisa de roles de usuario ayuda a identificar necesidades y eliminar complejidad innecesaria. Esto también ayuda a mejorar la gestión de los proyectos y la estrategia de planificación.

Evalúa la zona de control y la esfera de influencia

Hay tres áreas de sistemas diferentes:

  • La zona de control incluye todas las cosas en un sistema que podemos cambiar nosotros mismos.
  • La esfera de influencia incluye las actividades con las que podemos impactar, pero sobre las que no podemos ejercitar control total.
  • Los elementos externos incluyen elementos sobre los que no podemos influir.

La necesidad del usuario de una historia idealmente debería estar en la esfera de influencia del equipo, mientras que el entregable en su zona de control.

Pon una fecha de “best before” en las historias

Para evitar presiones innecesarias y emergencias auto inflingidas, comprueba si hay una fecha límite cuando una nueva historia de usuario es propuesta. Escribe la fecha de “best before” en esas historias y haz visualmente obvio que esas son especiales y tienen que gestionarse por separado.

No intentes poner fecha de “best before” en todas las historias, de lo contrario todo se convertirá en una emergencia.


Próximamente iré completando las traducciones de las recopilaciones del resto de bloques:

Planificando con historias

Discutiendo historias

Partiendo historias

Gestionando la entrega iterativa

Obviamente estas anotaciones no pretenden servir como sustitución al libro, pero tal vez resulte de inspiración para investigar más en profundidad alguna de estas ideas.

Variable not found: Enlaces interesantes 404

$
0
0
Enlaces interesantesEl popular código de estado HTTP 404 (Not found) indica que la conexión con el servidor ha podido ser establecida, pero el recurso solicitado no existe o bien el servidor prefiere hacer ver que no existe, quizás por razones de seguridad. Por defecto, este resultado puede ser cacheado en el cliente o elementos intermedios, salvo que se indique lo contrario.

Sin embargo, atendiendo a la especificación del protocolo HTTP, no siempre se utiliza correctamente. Por definición, la respuesta 404 no dispone de mecanismos para indicar si el recurso existió alguna vez o si el error es permanente o transitorio, mientras que el código HTTP 410 (Gone) sí permite expresar que el recurso existió, pero ya no está disponible y no volverá a estarlo, por lo que los clientes podrían eliminar enlaces o referencias al mismo con tranquilidad.

Y ahora, vamos a por los enlaces recopilados durante la semana pasada que, como es habitual, espero que os resulten altamente interesantes. :-)

Por si te lo perdiste...

.NET Core / .NET

ASP.NET Core / ASP.NET

Azure / Cloud

Conceptos / Patrones / Buenas prácticas

Data

    Web / HTML / CSS / Javascript

    Visual Studio / Complementos / Herramientas

    Xamarin

    Otros

    Publicado en Variable not found.

    Fixed Buffer: Como manejar las trazas de una aplicación .Net Core con Seq y Serilog

    $
    0
    0
    Tiempo de lectura:8minutos
    Imagen ornamental para la entrada "Como manejar las trazas de una aplicación .Net Core con Seq y Serilog"

    Esta semana he estado preparando una entrada para CampusMVP hablando de Serilog y lo útil que es instrumentar el código utilizando Serilog como herramienta para este fin.

    En esa entrada se plantea la importancia de añadir un buen sistema de trazas que sea fácilmente configurable según las necesidades de cada momento. Precisamente de esa entrada y de un proyecto en el que estuve hace unos meses viene la idea de esta entrada.

    ¿Cómo poder crear trazas estructuradas y consultarlas en vivo?

    Una de las principales necesidades cuando estamos revisando las trazas de una aplicación, es aporten suficiente información y que sean fáciles de consultar. Para esto es vital que definamos unas buenas trazas a lo largo del código y que sus niveles estén bien definidos.

    Por poner un caso concreto, si estas trazando una excepción utilizar el nivel ‘Debug’ seguramente no sea la mejor opción.

    Por otro lado, el hecho de utilizar trazas estructuradas nos facilita enormemente el poder ver que datos se estaban utilizando en el momento concreto y el poder analizar los datos de una manera más eficiente.

    Si has leído mi entrada en CampusMVP, ya sabes que entre los múltiples Sinks que ofrece Serilog hay varios que nos permiten tener información en tiempo real. Abrir y cerrar un fichero para ver los cambios no es una manera muy eficiente de revisar logs en tiempo real…

    Aquí es donde entra en juego Seq.

    ¿Qué es Seq?

    Seq es un sistema de ingesta de logs que permite hacer analítica de manera muy sencilla. Simplemente va a exponer un endpoint donde las aplicaciones van a publicar sus trazas. Además, ofrece de serie una interfaz donde vamos a poder ver todas las trazas y hacer consultas sobre ellas:

    La imagen muestra la interfaz de Seq con una consulta cualquiera. Las trazas que se muestran son las que cumplen la consulta.

    Aunque es una herramienta de pago, tiene un nivel gratuito que se puede utilizar incluso de manera comercial en producción (y esa es la razón de hablar en esta entrada).

    Para poder utilizarlo hay que crear un servidor Seq ya sea instalando el software en un equipo o mediante Docker.

    Si acostumbras a utilizar Docker en tus desarrollos y tienes dudas sobre donde o cómo hacer las pruebas, no te pierdas sobre cómo ejecutar pruebas de código dentro de contendores Docker.

    Utilizando Seq en una aplicación .Net Core con Serilog

    Vale, ahora que ya tenemos Seq en nuestro equipo, sea utilizando el instalador o mediante Docker, es hora de configurar Serilog en una aplicación .Net Core para enviar las trazas a Seq.

    Importante: En este punto se asume que has leído la entrada sobre como instrumentar el código utilizando Serilog y sabes cómo funciona Serilog. Si tienes dudas sobre como funciona échale un ojo a esa entrada primero.

    Para poder enviar las trazas de Serilog a Seq, basta con añadir el Sink de Seq utilizando el paquete NuGet ‘Serilog.Sinks.Seq‘. Una vez hecho eso, simplemente vamos a configurar el Sink para que funcione correctamente. La única configuración obligatoria que necesitamos de momento es el endpoint de ingesta de Seq, que por defecto es ‘http://localhost:5341’

    var logger = new LoggerConfiguration()
                    .MinimumLevel.Debug()
                    .WriteTo.Seq("http://localhost:5341")
                    .CreateLogger();
    

    Si sobre ese logger que hemos creado, escribimos mensajes como por ejemplo:

    logger.Verbose("Mensaje Verbose");
    logger.Debug("Mensaje Debug");
    logger.Information("Mensaje Information");
    logger.Warning("Mensaje Warning");
    logger.Error("Mensaje Error");
    logger.Fatal("Mensaje Fatal");
    

    Vamos a poder ir a la web de administración built-in de Seq y encontrarnos algo como esto:

    La imagen muestra el panel de eventos de Seq donde se pueden ver las trazas: Mensaje Fatal, Mensaje Error, Mensaje Warning, Mensaje Information y Mensaje Debug

    Como era de esperar ‘Mensaje Verbose’ no aparece ya que el nivel mínimo que debe tener una traza para enviarla a Seq según la configuración que hemos dado al logger es ‘Debug’

    Al igual que ocurría con el resto de sinks y enrichers de Serilog, el sink de Seq puede utilizar el fichero de appsettings.json de .Net Core o app.congif/web.config de .Net para configurarse:

    {
      "Serilog": {
        "WriteTo": [
          { "Name": "Seq", "Args": { "serverUrl": "http://localhost:5341" } }
        ]
      }
    }
    

    ¿Cómo gestiona Seq las trazas estructuradas desde Serilog en .Net Core?

    Una de las grandes ventajas de utilizar Serilog en .Net Core y enviar las trazas a Seq, es que estas no se limitan a mensajes de texto, sino que pueden contener información mucho más compleja.

    Imaginemos que tenemos una clase como pudiera ser:

    public class Pedido
    {
        public int IdPedido { get; set; }
        public string Dirección { get; set; }
    }
    

    Si no utilizásemos trazas estructuradas y quisiésemos registrar en el log la información del pedido que ha producido un error, tendríamos que hacer algo como este:

    logger.Error($"Se ha producido un error registrando el pedido. Id: {pedido.IdPedido}, Direccion: {pedido.Dirección}");
    

    Si además añadiésemos un nuevo campo a la clase, tendríamos que revisar todas las trazas donde se usa para añadirlo, o no estaríamos registrando ese nuevo campo.

    En cambio, utilizando trazas estructuradas podemos hacer algo como esto:

    logger.Error("Se ha producido un error registrando el {@Pedido}.",pedido);
    

    De este modo además de que queda todo mucho más claro y legible, todas las propiedades se van a registrar independientemente de que la clase cambie.

    Para que Seq añada el contenido del objeto a la traza, hay que colocar una arroba (@) delante del objeto entre paréntesis

    A este punto, es importante señalas que quien está creando las trazas estructuradas de nuestra aplicación .Net Core es Serilog y no Seq. Es por esto que si comprobamos la salida de consola o de fichero podemos encontrar algo como esto:

    [20:52:52 ERR] Se ha producido un error registrando el pedido. Id: 2134, Direccion: www.fixedbuffer.com
    [20:52:52 ERR] Se ha producido un error registrando el {"IdPedido": 2134, "Dirección": "www.fixedbuffer.com", "$type": "Pedido"}.
    

    ¿Y qué ventaja nos aporta Seq entonces? Pues que es muy cómodo poder consultar esos datos:

    La imagen muestra desplegada una traza generada desde .Net Core con Serilog  y enviada a Seq, donde se lee: "Se ha producido un error registrando el Pedido", y junto al mensaje un json con los datos del pedido.

    Securizando la ingesta de trazas enviadas a Seq desde .Net Core con Serilog

    Si bien es cierto que con lo que hemos hecho hasta ahora ya tenemos listo Serilog para enviar trazas a Seq desde una aplicación .Net Core, el escenario es un tanto inseguro… Cualquiera que conozca el endpoint de ingesta puede mandar datos.

    Para poder solucionar esta situación, Seq nos ofrece la posibilidad de crear tokens que deberán utilizar las aplicaciones para enviar las trazas, ya sea desde Serilog o desde cualquier otro logger de .Net Core que soporte trabajar con Seq.

    Para conseguir ello basta con ir al menú ‘settings’ de la parte superior derecha y después pulsar sobre ‘Add API Key’

    La imagen señala los botones "settings" de la parte superior derecha y "ADD API KEY" de la parte inferior izquierda

    Eso nos lanzará una nueva ventana donde vamos a poder configurar diferentes aspectos de la key como su nombre, sus permisos, el nivel mínimo de trazas que va a registrar o diferentes filtros y propiedades.

    La imagen muestra la interfaz de creación de una key para una aplicación .Net Core con Serilog y Seq

    Una vez configurado, basta con pulsar sobre ‘Save Changes’ para guardar los datos y crear una key que se nos mostrará por pantalla.

    Importante: La key solo se mostrará una vez y no será posible recuperarla después, asi que toma nota de ella y ponla a buen recaudo

    Una vez tenemos la key, basta dársela a Serilog a través del parámetro ‘apiKey’, ya sea utilizando código o un fichero de configuración.

    Visualización mediante paneles

    Una de las cosas que más me gusta de Seq es la posibilidad que ofrece de monitorizar el estado de las aplicaciones sin ningún esfuerzo. Creas tu aplicación .Net Core, añades Serilog, configuras el sink de Seq, y a partir de ese momento puedes crear diferentes paneles donde visualizar la información relevante.

    La imagen muestra el panel de gráficas por defecto que ofrece Seq

    Para esto Seq ofrece una ventana de paneles donde es posible crear paneles propios aplicando consultas sobre la información que se registra.

    Extensión de la funcionalidad

    Aunque no quiero entrar muy a fondo en lo extensible que es Seq, si es muy útil conocer que se puede extender a través de más de 500 paquetes NuGet que añaden diferentes funcionalidades como por ejemplo el envío de alertas por correo electrónico, o incluso por Slack o Microsoft Teams.

    Para poder añadir estos paquetes que dotan de funcionalidad extra a Seq, bastan con ir al menú de ‘settings’, pero esta vez al submenú ‘Apps’.

    La imagen señala el botón "settings" de la parte superior derecha y el submenu APPS de la parte izquierda

    Desde esta ventana vamos a poder buscar los diferentes paquetes y podremos instalarlos con un simple click.

    Evidentemente luego hay que configurarlos, y que sea sencillo o no dependerá de cómo y para qué sea el paquete.

    Conclusión

    Para no extender mucho la entrada y que se haga eterna, hemos revisado por encima la principal funcionalidad que ofrece enviar las trazas de .Net Core a Seq con Serilog. La funcionalidad que he planteado es la que a mí me parece más interesante, pero eso no significa que sea la única.

    Seq ofrece una gran funcionalidad extra que facilitan mucho la vida a la hora de encontrar problemas sobre sistemas en producción, pero nada es gratis.

    Primero, el software, aunque ofrece un modo gratuito que se puede utilizar en producción, si necesitas una gestión de usuarios o un soporte avanzado, no te queda otra que pasar por caja…

    Después, está el coste computacional extra de enviar las trazas por una conexión de red, que, aunque es muy bajo, no es despreciable y hay que tenerlo en cuenta.

    Por último, el hecho de que ante un fallo catastrófico pueden quedarse trazas pendientes de enviar y no registrarse en Seq. Si que es cierto que Serilog y otros sistemas de logging ofrecen mecanismos para guardar las trazas temporalmente en un fichero de modo que evitemos esos casos, es trabaja extra por nuestra parte el configurarlos. Además, el sistema que tiene que gestionar ese trabajo extra así que hay que plantearse si es necesario cuando escribes código de alto rendimiento en .Net Core.

    Con todo, personalmente creo que Seq es una gran herramienta a tener en el cinturón, aunque solo sea durante la fase de desarrollo. Al fin y al cabo, se puede poner en marcha Seq desde un Docker y poner y quitar el sink son un par de líneas de código.

    ¿Y tú? ¿Crees que Seq puede ayudarte en tu día a día?

    **La entrada Como manejar las trazas de una aplicación .Net Core con Seq y Serilog se publicó primero en Fixed Buffer.**

    Variable not found: Componentes con cuerpo en Blazor

    $
    0
    0
    BlazorNormalmente, en demos y ejemplos de Blazor solemos ver el uso componentes sin cuerpo, muchas veces escritos en forma de tags autocerrados, como los siguientes:
    <Article Title="A new hope" DatePublished="@DateTime.Now"></Article>
    <Article Title="A new hope" DatePublished="@DateTime.Now" />
    El código de este componente, en Article.razor, podría ser el siguiente:
    <h1>@Title</h1>
    <p>Post content goes here...</p>
    @code {
    [Parameter]
    public string Title { get; set; }
    [Parameter]
    public DateTime DatePublished { get; set; }
    }
    En este punto, es lógico pensar que nuestro artículo tendrá su texto, por lo que deberíamos poder incluirle un cuerpo. Una posibilidad sería incluir en el componente una propiedad Body y enviarle el cuerpo en el momento de su instanciación, como en el ejemplo que vemos a continuación:
    <Article Title="A new hope" DatePublished="@DateTime.Now" Body="This is the post content..."></Article>
    Pero, como podréis imaginar, esto es bastante limitado. Aparte de la legibilidad nula que tendría a nivel de código si el texto es medianamente extenso, no podríamos utilizar marcado HTML ni otros componentes Blazor en su interior, por lo que no es una solución práctica. Lo que en realidad nos interesa es poder hacer lo siguiente:
    <Article Title="A new hope" DatePublished="@DateTime.Now">
    <p>This is the post content</p>
    <p>Blah, blah, blah...</p>
    </Article>
    Sin embargo, si probáis a ejecutar el código anterior obtendréis un error parecido al siguiente:
    InvalidOperationException: Object of type 'MyBlazorProject.Pages.Article' does not have a property matching the name 'ChildContent'.
    El mensaje de error no nos indica por qué ocurre, aunque apunta en la dirección para poder solucionarlo. Como no podría ser de otra forma, Blazor permite la creación de componentes con cuerpo.

    La propiedad ChildContent

    Cuando Blazor parsea un componente con cuerpo, intenta introducirlo en una propiedad de tipo RenderFragment que, por convención, se denomina ChildContent. Como podréis adivinar, cuando no la encuentra se lanza la excepción que veíamos anteriormente.

    Reescribamos nuestro componente para incluirle esta propiedad:
    <h1>@Title</h1>
    <div class="content">
    @ChildContent
    </div>

    @code {
    [Parameter]
    public string Title { get; set; }
    [Parameter]
    public DateTime DatePublished { get; set; }

    [Parameter]
    public RenderFragment ChildContent { get; set; }
    }
    Fijaos especialmente en dos cosas:
    • Primero, atendiendo a la convención, hemos añadido la propiedad ChildContent de tipo RenderFragment. En esta propiedad se introducirá el contenido especificado en el cuerpo del componente en el momento de utilizarlo.
       
    • Segundo, algo más arriba, justo debajo del título del post, hemos insertado @ChildContent en la zona de marcado HTML donde queremos que sea renderizado el cuerpo del componente.
    De esta forma, ya podemos suministrar a <Article> el cuerpo con toda la riqueza que Blazor nos permite, incluyendo tanto tags HTML como construcciones Razor:
    <Article Title="A new hope" DatePublished="@DateTime.Now">
    <p>This is the post content</p>
    <p>Today is @DateTime.Now</p>
    <p>Blah, blah, blah...</p>
    </Article>
    Fácil, ¿verdad?

    Aquí podríamos dar por terminado el post, pero todavía nos quedan cosas interesantes por descubrir...

    ¿Se pueden tener otras propiedades de tipo RenderFragment en el componente?

    Pues sí, y de hecho puede resultar bastante útil. Imaginad que queremos añadir a nuestro componente <Article> la posibilidad de utilizar en su cuerpo tags como <Summary> y <Body> para especificar el resumen y el contenido del artículo de la siguiente forma:
    <Article Title="A new hope" DatePublished="@DateTime.Now">
    <Summary>
    This article talks about a new hope.
    </Summary>
    <Body>
    <p>This is the post content</p>
    <p>Today is @DateTime.Now</p>
    <p>Blah, blah, blah...</p>
    </Body>
    </Article>
    Este sería un caso de uso de múltiples RenderFragment. Observad que aquí ya no nos interesa acceder al cuerpo completo del componente mediante la propiedad ChildContent, sino que queremos obtener por separado el sumario y el cuerpo.

    Para ello, la implementación del componente podría ser la siguiente:
    <h1>@Title</h1>
    <div class="summary">
    @Summary
    </div>
    <div class="content">
    @Body
    </div>

    @code {
    [Parameter]
    public string Title { get; set; }
    [Parameter]
    public DateTime DatePublished { get; set; }

    [Parameter]
    public RenderFragment Summary { get; set; }
    [Parameter]
    public RenderFragment Body { get; set; }
    }

    ¿Y podemos enviarle datos a un RenderFragment?

    Pues sí, y conceptualmente es algo muy parecido a lo que hacemos cuando en MVC enviamos a una vista tipada los datos que necesita para maquetarse. En el caso Blazor, podemos definir un fragmento como RenderFragment<T>, siendo T el tipo de datos que le suministraremos en el momento de renderizarlo.

    Así, cuando un RenderFragment<T> es renderizado, es necesario enviarle una instancia de T. Es decir, ya no incluiremos el fragmento en el marcado utilizando una expresión como @Fragmento (como hacíamos antes con @Summary o @Body), sino @Fragmento(obj), siendo obj la instancia de T que actuará como contexto de renderizado del fragmento.

    Por ejemplo, continuando con el escenario anterior, podríamos definir nuestro componente <Article> como aparece algo más abajo, donde indicamos que tanto Summary como Body son fragmentos tipados que recibirán una instancia de Article, el componente que los contiene. O en otras palabras, Summary y Body son fragmentos que se renderizarán usando como contexto un objeto de tipo Article:
    [Parameter]
    public RenderFragment<Article> Body { get; set; }
    [Parameter]
    public RenderFragment<Article> Summary { get; set; }
    Ya en el marcado HTML, en el momento de renderizar estos fragmentos debemos suministrarles la instancia que actuará como contexto. Dado que en este caso estamos en el interior de la clase Article, podemos utilizar this:
    <h1>@Title</h1>
    <div class="summary">
    @Summary(this)
    </div>
    <div class="content">
    @Body(this)
    </div>

    @code {
    [Parameter]
    public string Title { get; set; }
    [Parameter]
    public DateTime DatePublished { get; set; }

    [Parameter]
    public RenderFragment<Article> Body { get; set; }
    [Parameter]
    public RenderFragment<Article> Summary { get; set; }
    }
    ¿Y cómo podemos utilizar el contexto a la hora de definir el contenido de los fragmentos? Pues sencillo. Por defecto, en el cuerpo de estos fragmentos tendremos definida una variable llamada context que nos dará acceso al contexto:
    <Article Title="A new hope" DatePublished="@DateTime.Now">
    <Summary>
    This article was posted on @context.DatePublished.ToShortDateString()
    and talks about @context.Title.
    </Summary>
    <Body>
    <p>This is the post content</p>
    <p>Today is @DateTime.Now</p>
    <p>Blah, blah, blah...</p>
    </Body>
    </Article>
    Si el nombre context no nos convence demasiado podemos utilizar la propiedad Context de los RenderFragment para indicar el nombre de la variable con la que podremos acceder desde ellos a sus datos de contexto. Es decir, con  Context indicaremos el nombre que daremos localmente a dicha información para poder referirnos a ella.

    Quizás suene un poco confuso, pero una vez lo pillamos es simple. En el siguiente bloque de código utilizamos un componente <Article> en cuyo fragmento <Summary> especificamos que el contexto estará disponible localmente bajo el nombre article (que, como sabemos, es de tipo Article). Por esa razón, podemos acceder a él mediante @article:
    <Article Title="A new hope" DatePublished="@DateTime.Now">
    <Summary Context="article">
    This article was posted on @article.DatePublished.ToShortDateString()
    and talks about @article.Title.
    </Summary>
    <Body>
    <p>This is the post content</p>
    <p>Today is @DateTime.Now</p>
    <p>Blah, blah, blah...</p>
    </Body>
    </Article>
    Si lo pensáis un poco, veréis que este patrón es el mismo que se utiliza en el componente de routing de la aplicación que encontraréis en el archivo App.razor de todos los proyectos Blazor. En él, el fragmento <Found>, que es un RenderFragment<RouteData>, establece que su contexto estará disponible en la variable routeData, que es luego utilizada para proporcionar a <RouteView> el valor del atributo RouteData:
    <Router AppAssembly="@typeof(Program).Assembly">
    <Found Context="routeData">
    <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
    </Found>
    ...
    </Router>
    Espero que os resulte útil en vuestros desarrollos :)

    Publicado en Variable not found.

    Picando Código: Reclaiming Work – Documental sobre cooperativas de plataformas de delivery

    $
    0
    0

    Reclaiming Work (“Reclamando el trabajo”) es un documental producido por Black Brown Films sobre la “gig economy” y los ciclistas que hacen deliveries. Habla un poco desde el punto de vista de los trabajadores mismos sobre lo que está mal de la gig economy (como escribe Wendy Liu en “Abolish Silicon Valley”: la expresión más pura de software como medio para extender el poder del capital sobre los trabajadores) y una alternativa más sana: cooperativismo.

    Los trabajadors de estas empresas no tienen derechos laborales, seguro médico, vacaciones pagas, y demás. El sistema no es sustentable. Creo que Cory Doctorow lo expresa bastante bien: “Las plataformas de Delivery como Grubhub y Deliveroo son parasitarias, basureros prendidos fuego sangrando dinero que destripan los márgenes de los restaurantes y somete a los trabajadores a trabajo brutal y precario, sin obtener ganancias, pero para convencer a idiotas de comprar acciones”. Les recomiendo visitar este último enlace en Twitter, donde me enteré de este documental. Doctorow escribe más al respecto en este otro hilo de Twitter.

    Una solución a la injusticia e inviabilidad de estos negocios son las plataformas cooperativas. Los trabajadores son los dueños de los medios de producción, en este caso la plataforma y el servicio, asegurándose condiciones laborales dignas y una repartición justa de los ingresos. En el documental veremos testimonios de trabajadores de La Pájara Ciclomensajería de Madrid y otras cooperativas en Francia. Para conocer más, podemos también visitar el sitio CoopCycle, una federación de cooperativas de entrega por bicicleta.

    En palabras de los trabajadores:

    Tenemos que usar las últimas herramientas que fueron creadas por el capitalismo y extenderlas para implementar socialismo.

    Estamos tramando su desaparición con las mismas plataformas que construyero para ellos mismos.

    Si te gusta la literatura cyberpunk, éstos días hay que mirar al mundo real para encontrarla:

    YouTube Video

     

    Coding Potions: Angular avanzado - ¿Qué necesitas aprender?

    $
    0
    0

    Lleva tus bases al siguiente nivel

    Si has llegado hasta este punto significa que ya tienes una base básica de Angular y quieres aprender conceptos más avanzados para convertirte en un auténtico experto de este framework.

    En este artículo veremos una serie de puntos que pueden ser interesantes para seguir aprendiendo este framework.

    NGRX

    De todos los apartados que vamos a ver en este artículo este es el más esencial,todo el mundo debería saber NGRX ya que es fundamental en aplicaciones webs grandes y complejas.

    NGRX es la librería que aplica el patrón Redux muy de moda en este tipo de frameworks para el desarrollo web. Se trata de una librería que sirve para centralizar el estado de una aplicación web.

    Esto del estado lo tienes que ver como una forma de tener en un solo sitio una serie de datos e información que van a usar los componentes. Piensa en una web muy grande hecha con Angular. Si necesitas los mismos datos en distintos sitios de la web lo más común es usar servicios, pero, al final todo llega a ser demasiado lioso y además pierdes el control de los datos.

    Con NGRX tienes el estado de la aplicación en un solo lugar llamado store. El store es inmutable, eso quiere decir que los estados son solo de lectura y cada vez que quieras modificar uno tienes que devolver un objeto nuevo. Además para cambiar este estado hay que usar funciones puras llamadas acciones.

    • 🏪 Store: Contiene el estado global de la aplicación. Inmutable
    • 🔨 Reducers: Devuelven un nuevo estado accediendo al store. Funciones puras.
    • 👷 Actions: Hacen uso de los reducers. Normalmente tienen un tipo y un payload.
    • 🔎 Selectors: Se usan desde los componentes para seleccionar una parte del estado.

    Imagina que tienes en tu web un sistema de login de usuarios. Puedes usar el store para guardar dentro el usuario que está logueado en el sistema. Lo bueno de esto es que usando los selectores dentro del componente puedes tener el usuario logueado en los componentes que necesites.

    Además, si desde un componente utilizas un action para crear un nuevo estado cambiando el usuario logueado, desde los otros componentes lo tendrás actualizado sin tener que hacer nada.

    Si te fijas en el gráfico de arriba, también aparecen los “effects”. Los effects se encargan de controlar los “side effects” de fuentes externas, es decir, normalmente se usan en peticiones HTTP y en sockets. Estos effects pueden ser síncronos o asíncronos.

    Schematics

    Esta es una característica de Angular CLI. Se trata de una herramienta para generar código con una estructura. Es una especie de scaffolding de código pero más complejo porque también permite editar código existente e incluir lógica.

    Lo bueno de los schematics es que puedes crear los tuyos propios e incluso compartirlos en forma de librería para que otros los puedan usar.

    Imagina que quieres añadir un sistema de login a tu aplicación web. Una solución es crearlo tu mismo y modificar tu proyecto manualmente.

    Otra forma maś cómoda es un usar un shematic que añada un sistema de login. Al instalarse leerá tu proyecto y hará los ajustes necesarios (creando archivos y modificando los existentes) de tal forma que no tengas que cambiar tú manualmente el código.

    Como hemos dicho, lo mejor de los schematics es que puedes crear los tuyos propios. Esto permite que puedas crear tu propio conjunto de ficheros y utilidades instalables en cualquiera de tus proyectos. Por ejemplo, yo tengo creado para mis poryectos un schematic para poder generar en cualquier proyecto un archivo que me recoja los errores de forma global en todas las peticiones a las APIS para llevar al usuario a la página de error, y todo eso siendo instalable con un solo comando.

    PWA

    ¿Alguna vez al entrar en una web desde el móvil te ha salido un cartel diciendo que puedes instalar esa web? Eso es porque es una web PWA.

    Esto de las PWA es un concepto relativamente nuevo, pero cada vez lo están adoptando más webs. Para ciertos casos es muy recomendable que la web sea PWA y además implementarlo no es demasiado complejo.

    Que una web sea PWA realmente lo que significa es que la web puede ser utilizada de forma offline, por eso interesa especialmente en aplicaciones web. Para conseguir esto se hace uso de los service workers que lo que hacen es “cachear” la web para que se pueda abrir sin conexión.

    Al estar toda la web cacheada los tiempos de carga son casi nulos, esto permite que pueda ser instalada como una aplicación más del sistema. Cada vez más sistemas operativos y navegadores dan esta opción.

    Otra ventaja muy interesante de las aplicaciones PWA es que facilitan el uso de las notificaciones push. Las notificaciones push se trata de una forma de generar una notificación en el dispositivo del usuario de forma nativa. Lo bueno de las notificaciones push es que se pueden enviar en tiempo real desde el servidor aunque la aplicación web no se esté ejecutando.

    Internacionalización con i18n

    Internacionalización consiste en crear una web multilenguaje. Como en todos los frameworks, en Angular también existen sistemas para montar esta lógica sin que lo tengas que hacer todo a mano.

    Lo que se suele hacer es tener un archivo JSON por cada lenguaje (es.json, en.json, de.json, it.json…) con cada uno de las cadenas de texto en cada uno de los lenguajes.

    Lo que consigues con i18n es acceder a estas cadenas de texto dependiendo del lenguaje configurado en la aplicación web.

    Esto es lo básico pero se pueden hacer más cosas como gestionar las cadenas de texto en singular/plural de tal forma que no tengas que tener la misma dos veces. También puedes insertar variables dentro de la cadena pera que no tengas que crear varias para una frase e incluso puedes tener textos por defecto por si no se encuentra la cadena dentro de los locales.

    Testing

    Si tienes un proyecto grande es esencial tener una buena suite de tests para poder probar la aplicación sin tener que hacerlo manualmente.

    Los tests permiten tener la seguridad de que el código va a funcionar y asi evitamos posibles bugs a futuros. Los tests se suelen combinar con la integración continua para que siempre se hagan pruebas antes de realizar despliegues de la web.

    Hay varios tipos de tests:

    • Tests Unitarios: Consiste en probar unidades pequeñas. Lo suyo es testear componentes o pequeñas partes de los componentes de forma aislada. Para estos tests se suele usar Jasmine.

    • Tests de Integración: Consiste en probar el conjunto de la aplicación asegurando la correcta comunicación entre los distintos elementos de la aplicación. Por ejemplo, en Angular observando cómo se comunican los servicios con la API y con los componentes. Lo más usado en Angular es Karma, que añade a los tests el motor de renderización de los nevegadores.

    • Tests End to End (E2E): Consiste en probar toda la aplicación simulando la acción de un usuario, es decir, por ejemplo para desarrollo web, mediante herramientas automáticas, abrimos el navegador y navegamos y usamos la página como lo haría un usuario normal. En esta parte lo más usado es Protractor.

    Decoradores

    Si has usado Angular, aunque sea de forma básica, has tenido que usar decoradores, lo que pasa es que no te has dado cuenta. Cuando declaras un servicio inyectable con @Service o creas un componente con @Component realmente lo que estás haciendo es usar decoradores.

    Al principio no le veía el sentido a usar estos decoradores, no les encontraba el uso, pero con el paso del tiempo, me dí cuenta de que crear decoradores tiene mucho potencial y no solo me refiero a controladores para usar en Angular.

    Si, has leído bien, puedes crear tus propios controladores. Creando tus propios decoradores vas a agilizar mucho el desarrollo de aplicaciones de Angular porque los vas a definir una sola vez y los vas a poder reutilizar en muchos sitios.

    Los decoradores no son más que funciones que se ejecutan cuando Angular llama al decorador. La función puede recibir como parámetro la clase que se ha decorado (si es un decorador de clase), el atributo o parámetro o el método si es un decorador de método.

    Lo bueno es que además se pueden crear decoradores de varios tipos: de clase, de métodos y de propiedades por lo que se adaptan bien a cualquier proyecto.

    Animaciones

    animación css ejemplo

    Las animaciones son cada vez más importantes. Además de añadir dinamismo a las webs, hacen que las transicciones entre páginas o estados no sean tan abruptas y sea más suaves.

    Aunque puedes crear tus propias animaciones con CSS, o incluso tus propios componentes con Animaciones, Angular tiene una forma nativa de crear animaciones. Además de poder crearlas, ofrece un montón de formas de poder controlarlas y gestionarlas.

    Por ejemplo, puedes crear múltiples animaciones sobre una lista de tal forma que cada animación se vaya escalonando una detrás de la otra. También puedes controlar la finalización de la animación para poder ejecutar cosas a continuación.

    En definitiva, en la mayoría de casos no vas a echar en falta un sistema de animaciones como el de greenshock.

    Curso de Angular avanzado

    Si quieres aprender todo esto que hemos visto en este artículo y más conceptos avanzados te recomiendo que te inscribas en un curso avanzado de Angular.

    Te recomiendo que le eches un vistazo a este curso avanzado de Angular. Aparte de cubrir lo que hemos hablado en este artículo, aprenderás otros conceptos como inyección avanzada de dependencias, RxJS, directivas avanzadas y mucho más.

    Además, tengo una buena noticia que darte:

    ¡He conseguido un descuento exclusivo para ti de 100 €!

    Para conseguir este descuento solo tienes que rellenar el formulario o llamar por teléfono diciendo que vas de mi parte con el siguiente código: CODINGPOINT100.

    Te dejo aquí abajo el link al curso:

    Curso avanzado de Angular

    Conclusiones

    Espero que te haya gustado esta lista y sobre todo que te haya servido para orientarte o darte ideas sobre qué seguir aprendiendo de este fantástico framework.

    Esta lista no sigue ningún orden en particular y es mi visión personal, lo que yo opino.

    Por último, te recomiendo, si te interesa, que aprendas cómo está hecho Angular por debajo (mirando su código fuente en github). Aunque creas que no te va a servir, sabrás mejor por qué y cómo pasan las cosas y puede que te sirva para no cometer ciertos errores.

    Blog Bitix: La concurrencia en la plataforma Java con Project Loom

    $
    0
    0

    Desde la publicación de Java 8 junto con el nuevo calendario de publicación las mejoras en la plataforma Java y en el lenguaje han sido constantes y significativas. Las mejoras continúan en cada nueva versión y hay muchas otras en preparación para ser publicadas cuando estén listas. Una de ellas muy prometedoras es una nueva implementación de los threads mucho más ligera que han existido desde la primera versión. Estos harán innecesarios en la mayoría de los casos los más complicados modelos programación asíncrona, la programación reactiva, la programación mediante callbacks y las construcciones async/await.

    Java

    Los threads han existido en Java desde la primera versión siendo uno de sus componentes esenciales. Los threads representan una unidad de trabajo concurrente como una abstracción de los recursos computacionales disponibles y que ocultan la complejidad de gestionar esos recursos.

    Ya se usen de forma directa o dentro de un framework como JAX-RS la concurrencia en Java significan threads. En realidad, la plataforma Java entera, desde la máquina virtual al lenguaje y librerías incluidos depuradores y profilers está construida alrededor de los threads como componente esencial de ejecutar un programa.

    En general la plataforma Java se basa en:

    • Las APIs son síncronas y describen operaciones E/S de inicio y espera a sus resultados como una secuencia ordenada de sentencias por threads que se bloquean.
    • Las operaciones de memoria con efectos colaterales son ordenadas secuencialmente por las acciones del thread.
    • Las excepciones proporcionan información útil indicando la operación fallida en el contexto del thread actual.
    • Los depuradores siguen el orden de ejecución aunque se realice procesado de E/S.

    Los problemas de los threads y sus alternativas

    En la implementación de Linux los threads no se diferencian de los procesos. Los threads son costosos de crear y pesados por lo que el sistema operativo solo es capaz de mantener unos pocos miles activos. Por este motivo ha surgido la programación asíncrona, la programación reactiva, la programación mediante callbacks y las construcciones async/await y frameworks basándose en estos principios como Vert.x o Spring Reactive o librerías como RxJava. El resultado es una proliferación de APIs asíncronas desde NIO en el JDK a los servlets asíncronos a las librerías denominadas reactivas para no bloquear los threads.

    Sin embargo, estas formas de programación tienen un costo mayor que el tradicional y simple modelo secuencial. Son más difíciles de programar, más difíciles de mantener e implican cambios importantes en el modelo de programación. Por otro lado es más difícil depurarlos ya que no se mantiene en una única pila de llamadas toda la tarea.

    Estos estilos de programación no han sido inventados porque sean más fáciles de entender, son más difíciles también de depurar y de hacer profile. Son muy intrusivos y hacen la integración con el código síncrono virtualmente imposible simplemente porque la implementación de los threads es simplemente inadecuada en Java tanto en carga del sistema como rendimiento. La programación asíncrona es contraria al modelo original diseñado en la programación de la plataforma Java en varios aspectos con un alto coste de mantenibilidad y observabilidad. Pero lo hacen por una buena razón, para conseguir la escalabilidad y el rendimiento haciendo buen uso de los costosos recursos hardware.

    La nueva implementación de los threads

    El proyecto Loom persigue crear unos threads que eliminen los costes de los hilos tradicionales del sistema operativo. Serán mucho más ligeros, con ellos Java será capaz de mantener varios órdenes de magnitud superior, millones de threads en vez de solo unos pocos miles. Estos threads virtuales o fibras de la plataforma Java son también simplemente threads pero que crearlos y bloquearlos es mucho más barato. Son gestionados por el entorno de ejecución de Java y no son una representación uno a uno de un envoltorio de los threads del sistema operativo, en vez de eso están implementados en el espacio de usuario del JDK.

    Los hilos de los sistemas operativos son pesados porque deben soportar todos los lenguajes y tipo de cargas de forma genérica. Un thread requiere la habilidad de suspender y reactivar su ejecución de la computación. Esto requiere preservar su estado, lo que incluye su puntero de instrucciones así como todo los datos locales de computación que son almacenados en la pila. Dado que el sistema operativo no conoce cómo implementa el lenguaje su pila debe reservar una suficientemente grande.

    Loom añade la habilidad de controlar la ejecución, suspensión y reactivación manteniendo su estado no como un recurso del sistema operativo sino como un objeto Java conocido por la máquina virtual bajo el control directo del entorno de ejecución. El conocimiento de las estructuras internas del lenguaje hace que mantener su estado sea más pequeño en comparación con el que mantiene el sistema operativo. Cuando un thread invoca una operación bloqueante se traspasa el control a otro thread con un coste mucho menor que el realizado por el sistema operativo.

    El proyecto Loom modificará muchas de las clases de forma interna para implementar los threads con los thread virtuales. Las librerías y aplicaciones que hagan uso de estas clases se beneficiarán de estas mejoras sin necesidad de realizar ninguna modificación.

    Estos párrafos son varios extractos del magnífico artículo State of Loom.

    Programmers are forced to choose between modeling a unit of domain concurrency directly as a thread and wasting considerable throughput that their hardware can support, or using other ways to implement concurrency on a very fine-grained level but relinquishing the strengths of the Java platform. Both choices have a considerable financial cost, either in hardware or in development and maintenance effort.

    We can do better.

    Project Loom intends to eliminate the frustrating tradeoff between efficiently running concurrent programs and efficiently writing, maintaining and observing them. It leans into the strengths of the platform rather than fight them, and also into the strengths of the efficient components of asynchronous programming. It lets you write programs in a familiar style, using familiar APIs, and in harmony with the platform and its tools — but also with the hardware — to reach a balance of write-time and runtime costs that, we hope, will be widely appealing. It does so without changing the language, and with only minor changes to the core library APIs. A simple, synchronous web server will be able to handle many more requests without requiring more hardware.

    Whereas the OS can support up to a few thousand active threads, the Java runtime can support millions of virtual threads. Every unit of concurrency in the application domain can be represented by its own thread, making programming concurrent applications easier. Forget about thread-pools, just spawn a new thread, one per task. You’ve already spawned a new virtual thread to handle an incoming HTTP request, but now, in the course of handling the request, you want to simultaneously query a database and issue outgoing requests to three other services? No problem — spawn more threads. You need to wait for something to happen without wasting precious resources? Forget about callbacks or reactive stream chaining — just block. Write straightforward, boring code. All the benefits threads give us — control flow, exception context, debugging flow, profiling organization — are preserved by virtual threads; only the runtime cost in footprint and performance is gone. There is no loss in flexibility compared to asynchronous programming because, as we’ll see, we have not ceded fine-grained control over scheduling.

    However, the existence of threads that are so lightweight compared to the threads we’re used to does require some mental adjustment. First, we no longer need to avoid blocking, because blocking a (virtual) thread is not costly. We can use all the familiar synchronous APIs without paying a high price in throughput. Second, creating these threads is cheap. Every task, within reason, can have its own thread entirely to itself; there is never a need to pool them. If we don’t pool them, how do we limit concurrent access to some service? Instead of breaking the task down and running the service-call subtask in a separate, constrained pool, we just let the entire task run start-to-finish, in its own thread, and use a semaphore in the service-call code to limit concurrency — this is how it should be done.

    Using virtual threads well does not require learning new concepts so much as it demands we unlearn old habits developed over the years to cope with the high cost of threads and that we’ve come to automatically associate with threads merely because we’ve only had the one implementation.

    La API de threads

    La forma de programación con los nuevos threads es muy parecida a la tradicional que ha existido siempre. Se parece tanto a los threads de siempre que incluso ni siquiera cambia la clase que los representa, que sigue siendo Thread, las diferencias de implementación son internas a la clase y en la JVM. En estos ejemplos se ejecutan tareas de dos formas diferentes y en la tercera se envían tareas para su ejecución y posteriormente se espera a obtener el resultado.

    1
    2
    
    Threadthread=Thread.startVirtualThread(()->System.out.println("Hello"));thread.join();
    threads-api-1.java
    1
    2
    3
    4
    5
    6
    
    Threadthread1=Thread.builder().virtual().task(()->System.out.println("Hello")).build();Threadthread2=Thread.builder()                      .virtual()                      .name("bob")                      .task(()->System.out.println("I'm Bob!"))                      .start();
    threads-api-2.java
    1
    2
    3
    4
    5
    
    ThreadFactorytf=Thread.builder().virtual().factory();ExecutorServicee=Executors.newUnboundedExecutor(tf);Future<Result>f=e.submit(()->{...returnresult;});// spawns a new virtual thread
    ...Resulty=f.get();//joinsthevirtualthread
    threads-api-3.java

    Conclusión

    Esta nueva implementación de los threads es una mejora significativa sobre la implementación original basada en el sistema operativo. Una vez esté disponible en una versión del JDK muchas aplicaciones se beneficiarán de forma transparente de sus mejoras simplemente por usar un JDK más reciente. Como es principio en la plataforma Java estos cambios están implementados de forma que sean compatibles hacia atrás para que no haya que realizar ningún cambio o muy pocos en las aplicaciones o librerías para beneficiarse de ellos.

    El modelo secuencial de los threads más simple que la programación reactiva, asíncrona, callbacks o las construcciones async/await tiene ventajas en la creación del software en su mantenibilidad, legibilidad y es beneficioso desde el punto de vista económico.

    Loom es un nuevo ejemplo de que Java no adopta las nuevas tendencias de forma inmediata sino que espera a ver como se desarrollan, y después de evaluar todas las posibilidades opta por una que en este caso es mejor que la programación reactiva o asíncrona que otros lenguajes para permitirlas han tenido que realizar modificaciones comprometiendo la compatibilidad en el futuro del código fuente o desaconsejando el uso de funcionalidades para eliminarlas en el futuro.

    Este artículo es simplemente un resumen de otros dos magníficos artículos State of Loom que explica todo esto en mayor profundidad. Muy recomendables su lectura junto a otros relacionados con Loom.

    Y otros artículos sobre Loom.

    Blog Bitix: El problema de seguridad tabnabbing y phising en los enlaces en nuevas pestañas a páginas externas y cómo solucionarlo

    $
    0
    0

    A medida que las personas dependen en mayor medida para operar en internet como compras, acceso a cuentas bancarias o trámites administrativos la seguridad de las aplicaciones web es más crítica. Una parte de la seguridad es responsabilidad del usuario pero otra parte importante es responsabilidad del sitio web. Un potencial problema de seguridad está en los simples y aparentemente inocentes enlaces abiertos en nuevas páginas si al mismo tiempo es posible insertar contenido en la página que otros usuarios obtengan. El resultado es una vulnerabilidad de tabnabbing y phising.

    HTML

    Es bueno conocer los problemas de seguridad más comunes en las aplicaciones web. Aún siendo la lista de los 10 problemas de seguridad más importantes muy conocidos aún siguen siendo de los más importantes por seguir habiendo aplicaciones vulnerables a ellos y por su gravedad para la seguridad de los datos así como para explotar una aplicación.

    Aún así no son los únicos importantes, algunos ni siquiera requieren complejas técnicas para explotarlos. Uno de ellos son los enlaces externos que se abren en páginas en blanco. El problema de seguridad reside en que el modo de funcionamiento por defecto de estos enlaces se permite el acceso a la ventana origen desde la página abierta. Esto hace que la página abierta potencialmente sea capaz de tomar el control de la ventana origen y modificar su contenido, por ejemplo cargando una página maliciosa para hacer un peligroso ataque de suplantación de identidad o phising que simule una página legítima con la intención de robar las contraseñas de algún servicio importante de un usuario.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    
    <!DOCTYPE html><htmllang="en"><head>    <metacharset="utf-8"/>    <title>Page</title></head><body>    <p><ahref="external.html"target="_blank">Open page</a></p>    <p><ahref="external.html"target="_blank"rel="noopener noreferrer">Open page (secure)</a></p></body></html>
    page.html

    Página con enlaces a otras páginas abiertas en una ueva pestaña

    Página con enlaces a otras páginas abiertas en una ueva pestaña

    El problema es que los navegadores cuando se abre un enlace en una página en blanco o nueva, el navegador hace accesible a la ventana abierta el objeto Window de la página que lo abre. Y teniendo acceso al objeto Window una página maliciosa cargada tiene la posibilidad de cargar una nueva página en la página original o acceder a las cookies entre ellas las que permiten mantener la sesión en el servidor. Por ejemplo, con la variable window.location es posible cargar una página de autenticación falsa que le pida al usuario introducir sus datos y realmente realice el robo de la contraseña.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    
    <!DOCTYPE html><htmllang="en"><head>    <metacharset="utf-8"/>    <title>Unknown</title>    <scripttype="text/javascript">        window.opener.location='https://www.google.com';        document.write('You have heen tabnabbed!');    </script></head><body></body></html>
    external.html

    Es un problema peligroso porque se aprovecha de los navegadores basados en pestañas, en este caso en una página fuera de la atención del usuario se carga un contenido nuevo, el usuario inadvertido al volver a esa pestaña puede pensar que el contenido cambiado de esa pestaña es legítimo sin ser consciente de que no lo es, sin embargo, ser víctima de este peligro de seguridad conocido como tabnabbing combinado con phising. Por ello se recomienda y es importante comprobar que el dominio de la página mostrado por el navegador en la barra de direcciones se corresponda con el contenido, que la página utilice un protocolo seguro no es suficiente si el ataque es de phising.

    Este ataque es realmente sencillo pero ha de complementarse con una forma de ataque XSS no tanto por permitir insertar código JavaScript pero si por permitir insertar contenido inseguro sin control de forma que otros usuarios tangan posibilidad de abrirlos y ser potenciales victimas en este caso enlaces que abran una página maliciosa.

    El enlace que abre una página en una nueva pestaña es vulnerable a tabnabbing. Al ir al enlace se abre una pestaña, el usuario pierde el foco de la página original y en ella la página abierta carga una nueva página produciéndose el tabnabbing.

    Problema de tabnnabing en enlaces que abren páginas en uneva pestaña

    Problema de tabnnabing en enlaces que abren páginas en uneva pestaña

    Problema de tabnnabing en enlaces que abren páginas en uneva pestaña

    La solución más sencilla es añadir el atributo rel="noopener noreferrer” a los enlaces que se abran en una nueva página, esto informa al navegador para que no proporcione a la página abierta el acceso a la variable window.opener, como se muestra en el segundo enlace del ejemplo de código page.html, si la página abierta hace uso de ella se produce un error de JavaScript.

    La variable window.opener es nula en el enlace seguro

    La variable window.opener es nula en el enlace seguro

    Otras medidas recomendables son codificar los datos para evitar ataques XSS y filtrar el contenido enviado por los usuarios o devuelto por la página sobre todo si proviene de fuentes externas a la aplicación ya sea de formularios introducidos por el usuario, parámetros, cabeceras u otras aplicaciones.

    Referencia:

    Picando Código: Nintendo Switch: SNK Gals’ Fighters

    $
    0
    0

    SNK Gals' Fighters

    SNK Gal’s Fighter es un juego de peleas de SNK, una empresa con una reputación más que conocida cuando se trata de juegos de luchas. Salió originalmente en el año 2000 para la console Neo Geo Pocket Color. Ahora podemos revivir el principio del milenio con una versión para Nintendo Switch publicada en el eShop de Nintendo. Tenemos para elegir de entre 11 luchadoras de distintos títulos de SNK como King Of Fighters, Samurai Shodown y Art Of Fighting. Además de las 11 luchadoras originales, podemos desbloquear 3 personajes escondidos.

    El modo de juego normal es el clásico de ir luchando contra distintas oponentes hasta llegar a la jefa final: “Miss X”. Los personajes cuentan con poderes típicos de sus apariciones anteriores, pero también algunos movimientos nuevos. A simple vista parece un juego súper simple, pero es bastante complejo para ser un juego de peleas con dos botones. Cada personaje tiene varios poderes y las peleas son entretenidas a pesar de las limitaciones del hardware.

    Si bien podemos atacar con movimientos especiales, incluso tenemos la barrita que se va llenando hasta 3 niveles como para atacar con “súper poderes”, encontré que lo más eficiente es atacar con combos. Las luchadoras controladas por el CPU bloquean casi todos los poderes especiales, así que la mejor estrategia me resultó ir probando y descubriendo combos para enganchar varios golpes de una, y de repente meter un movimiento especial en el medio. Tenemos disponible un modo de entrenamiento para poder practicar los poderes especiales y combos. Algo que no he probado todavía es jugar contra alguien más, pero se puede luchar contra amigos en los modos sobremesa o portátil del Switch.

    La versión de Switch tiene varias características nuevas que generalmente encontramos en otros juegos emulados. En la pantalla, podemos elegir de entre varios skins del Neo Geo Pocket Color, hacer zoom para variar entre ver la consola dentro de nuestra consola (o pantalla) o simplemente aumentar el tamaño para ver sólo el gameplay. También incluye un filtro para ver el gameplay como lo veríamos en la consola original. Otra característica es la posibilidad de rebobinar, algo que me resulta un poco “tramposo” en este tipo de juegos, pero de última está bueno que esté. Por último, incluye el manual original del juego en formato digital para ver en nuestro Switch.

    [See image gallery at picandocodigo.net] [See image gallery at picandocodigo.net] El Neo Geo Pocket Color salió unos meses después que el Game Boy Color. Nunca había jugado a ninguno de sus juegos y por alguna razón esperaba algo similar a los juegos de Game Boy Color. Pero me sorprendió ver lo bueno y dinámicos que son. La pantalla no tenía una capacidad técnica muy espectacular, pero el uso creativo dentro de las limitaciones gráficas genera resultados bastante buenos. Quedé sorprendido con lo rápido y fluido que es y la complejidad que puede llegar a tener un juego de peleas a pesar de las limitaciones de procesamieto y hardware.

    YouTube Video

    Ojalá SNK decida publicar más juegos de Neo Geo Pocket Color en el futuro. Hay títulos bastante interesantes, en particular me gustaría ver SNK vs. Capcom: Match of the Millennium, un King of Fighters o Fatal Fury.

    SNK Gal’s Fighter está disponible ahora en el Nintendo eShop:
    https://www.nintendo.com/games/detail/snk-gals-fighters-switch/

    Y sí -como yo- se quedaron con ganas de más juegos de lucha de SNK, en la eShop hay varios títulos de Neo Geo como King Of Fighters (94, 95, 96, 97… etc), The Last Blade, Art Of Fighting, Fatal Fury y Samurai Shodown. Un catálogo impresionante


    proyectos Ágiles: Master en Agile – MMA 2020

    $
    0
    0

    En octubre de 2020 se iniciará el Barcelona la 7ª edición del Postgrado en Métodos Ágiles (PMA) y otra del Máster en Transformación Agile (MMA) en La Salle (Universitat Ramon Llull), el primero a nivel mundial sobre Agile.

    MMA-banner

    El Máster incluye el Certified Scrum Master (CSM) de la Scrum Alliance y la certificación Kanban Systems Design de la Lean Kanban University.

    SAI_BadgeSizes_DigitalBadging_CSM

    Certified Kanban Training

    Esta es una oportunidad única para aprender de profesionales de primer nivel, con varios años de experiencia específica en Agile, aplicando principios y métodos ágiles en contextos diversos, especializándose en aspectos concretos,  investigando sobre nuevas técnicas y ponentes en conferencias nacionales e incluso internacionales.

    PMA – Postgrado en métodos Ágiles

    El PMA incluye el Certified Scrum Master (CSM) de la Scrum Alliance.

    AsignaturasTemasProfesores
    Fundamentos & Inception

    Principios y métodos más conocidos (Scrum, Lean, Kanban y XP). Facilitadores e impedimentos. Inception y conceptualización ágil de proyecto, priorización ágil, historias de usuario,  elaboración de Product Backlog, técnicas de priorización.

    Silvia Sistaré
    Agustín Yagüe
    Scrum y KanbanEstimación y planificación ágil, framework de Scrum, retrospectivas, Kanban, métricas ágiles, herramientas ágiles físicas, radiadores de información.Tiago Garcez
    Teodora Bozheva
    Personas y equiposGestión de personas, gestión de conflictos, motivación e incentivos, facilitación compartida, contratación ágil, visual thinking.Steven Wallace

     

    Manuel Lopez

    Silvia Sistaré

    Virginia Armas

    Gestión de producto ágil

    Design Thinking.

    Lean Startup & Agile Product Management

    Ángel Díaz-Maroto

    Gabriel Prat

    Ingeniería ágil 

    User eXperience y prototipado en Agile.

    ALM ágil, eXtreme Programing, Software Craftsmanship, testing ágil.

    BDD y TDD. Desarrollo guiado por pruebas (de aceptación y unitarias).

    Cómo trabajar con código heredado y reducir la deuda técnica.

    Marc Pifarré

     

    Álvaro García

    Pablo Gómez

     

    Rubén Bernárdez

    Trabajo Final de PostgradoDurante el Postgrado se elaborará un caso práctico de introducción de los contenidos en un equipo ágil. Para ellos los alumnos se organizarán en equipos multidisciplinares utilizando Scrum. 

    MMA – Master en Métodos Ágiles

    Incluye todas las asignaturas del Postgrado (PMA), el CSM, la certificación Kanban Systems Design de la Lean Kanban University y, adicionalmente, las siguientes asignaturas especializadas en Business Agility, agilidad organizacional y transformación:

    AsignaturasTemasProfesores
    Enterprise Learning & personal efficiency

    Agile Kaizen, Comunidades de Práctica, Open Spaces, Talent development, gamification.

    Productividad y aprendizaje personal en Agile (eficiencia).

    Steven Wallace
    Manuel Lopez
    Jordi Molla
    Lean Thinking & Agile Management

    Lean

    Escalado con Kanban.

    Visual Management Framework (VMF- Agile para cualquier área – Fuera de tecnología).

    Agile-Lean Management

    Teodora Bozheva

    Xavier Quesada

    Xavier Albaladejo

    Coaching y Cultura

    Coaching de equipos, creación de equipos de alto rendimiento, liderazgo.

    Tipos de cultura empresarial, gestión del cambio organizativo.

    Joserra Díaz

    Jasmina Nikolic
    Jaume Gurt

    Transformación Continua

    Enterprise continuous improvement.

    Despliegue de Agile en organizaciones. Contratos ágiles.

    Enterprise software development & DevOps.

    Ángel Medinilla
    Xavier Albaladejo

    Álvaro García

    Scaling Agile 

    Escalado (LESS, Spotify, Nexus, SAFe), desescalado y auto-organización empresarial (reinventing organizations, sociocracy 3.0, liberating structures, …), equipos distribuidos.

    Impact Mapping, Product Portfolio Management, Roadmapping, Budgeting for Agile

    Adrian Perreau
    Fernando Palomo

    Mattijas Larsson

    Trabajo Final de MásterDurante el Máster se elaborará un caso práctico de introducción y aplicación de Agile en una empresa, incluyendo la parte de transformación organizativa, de métodos y de cultura. Para ellos los alumnos se organizarán en equipos multidisciplinares utilizando Scrum. 

    Algunos comentarios de los alumnos en ediciones anteriores: “Cuando se acaba la clase, estamos ya esperando a que llegue la semana que viene para ver un nuevo tema con el siguiente profesor”. “Muy práctico”. “La calidad y diversidad de puntos de vista entre los profesores le aporta mucho valor”.  Más detalles en: Mejora de la situación laboral los alumnos del PMA trans un año.

     
    Además de los conocimientos concretos que se reciben, uno de los principales cambios que han experimentado los alumnos es mayor perspectiva en los problemas, cómo abordar la complejidad en las empresas, en su trabajo y en las relaciones entre personas y en equipos. Han ganado discurso y aplomo para defender de manera más objetiva propuestas de cambio y mejora.
     

    El Máster tendrá una duración de un año académico y se realizará viernes tarde y sábado por la mañana.

     
    Para más detalles, consultar la página oficial del Máster.
     

    Variable not found: Enlaces interesantes 405

    $
    0
    0
    Enlaces interesantesEl código de estado HTTP 405 es utilizado por los servidor para indicar a un cliente que el recurso solicitado existe, pero el método empleado para tener acceso al mismo no es correcto. Esto podemos verlo si, por ejemplo, hacemos una petición de tipo POST a un endpoint que sólo soporta PUT, o cualquier otra combinación incorrecta.

    Además del error 405, como parte de la respuesta, el servidor debe añadir un encabezado Allow con una lista de métodos soportados:
    GET http://192.168.1.33:55678/api/example HTTP/1.1

    HTTP/1.1 405 Method Not Allowed
    Allow: POST, PUT
    Y ahora, ahí van los enlaces recopilados durante la semana pasada que, como no podía ser de otra forma, viene cargado de novedades presentadas en el Build 2020. Espero que os resulten interesantes. :-)

    Por si te lo perdiste...

    .NET Core / .NET

    ASP.NET Core / ASP.NET

    Azure / Cloud

    Conceptos / Patrones / Buenas prácticas

    Data

    Machine learning / IA / Bots

    Web / HTML / CSS / Javascript

    Visual Studio / Complementos / Herramientas

    Xamarin

    Otros

    Publicado en Variable not found.

    PHP Senior: Fira Code: monospaced font with programming ligatures

    Picando Código: Cities: Skylines y DLCs a partir de USD 1 en el Humble Cities: Skylines Bundle

    $
    0
    0

    Hace un tiempo escribí sobre Cities: Skylines, el juego simulador de ciudades que estábamos esperando. Si todavía no lo han probado, pueden adquirir el juego original junto al DLC Deep Focus Radio por apenas 1 unidad de dinero (1 dólar si están en América, 1 libra si están en el Reino Unido, 1 euro si están en Europa, etc). El juego y sus DLCs están disponibles en Steam para GNU/Linux, Mac y Windows.


    Humble Cities: Skylines Bundle

    Pagando el mínimo obtenemos claves Steam para el juego original y el DLC Deep Focus Radio. Pagando más del promedio (variable) el paquete incluye estos DLCs:

    • Cities: Skylines – Concerts: mini-expansión para planear y presentar conciertos.
    • Cities: Skylines – Content Creator Pack: High-Tech Buildings: paquete de 15 edificios arqui-tecnológicos.
    • Cities: Skylines – Snowfall: mod para agregar nieve, lluvia y niebla al sistema de clima del juego con los desafíos que conlleva.
    • Cities: Skylines – Natural Disasters:Éste suena bastante interesante, es un catálogo de catástrofes naturales para un desafío mayor, además de sistemas de advertencia, rutas de emergencia, y demás. También incluye un editor de escenarios. Los desastres naturales incluyen terremotos, tormentas eléctricas, tsunamis, incendios forestales, tornados, pozos y meteoros. No menciona nada de Kaijus, pero no pierdo las esperanzas…

    Pagando USD 25, £ 14.50 o € 16.50, obtenemos los siguientes DLC:

    • Cities: Skylines – Mass Transit: expansión con varios sistemas de tránsito para el agua, montañas y el aire, ferris, monorieles, dirigibles y más.
    • Cities: Skylines – Green Cities: expansión para construir ciudades verdes con edificios ecológicos, tiendas orgánicas, coches eléctricos y demás.
    • Cities: Skylines – Industries: expansión para las zonas industriales con más recursos, servicios y fábricas.
    • Cities: Skylines – Campus: expansión con nuevos tipos de áreas para estudiantes.
    • Cities: Skylines – Content Creator Pack: Art Deco: expansión con edificios nuevos: 6 residenciales, 6 comerciales y 3 únicos. Los ingresos de este paquete se comparten con el usuario que creó los mods!
    • Cities: Skylines – Content Creator Pack: European Suburbia: Otro pack de contenidos con edificios residenciales con estilo europeo.

    Además de elegir cuánto pagar, parte de lo recaudado se divide entre charity: water y otra beneficencia que elijamos. Al pagar podemos elegir cuánto del dinero va para Paradox Interactive (los desarrolladores del juego), cuánto a beneficencia y cuánto a Humble Bundle. ¡No se lo pierdan! La oferta dura sólo 2 semanas. Creo que me voy a construir una ciudad nueva en Cities: Skyline…

    Humble Cities: Skylines Bundle

    Picando Código: Se acerca RuboCop 1.0

    $
    0
    0

    RuboCop es la herramienta de facto para analizar y formatear código en Ruby. Con miras de publicar la versión 1.0, Bozhidar Batsov -autor de Rubocop-, realizó una encuesta a la comunidad Ruby. RuboCop viene con un montón de valores por defecto, y la idea de la encuesta era medir lo que se viene usando para entender qué valores por defecto valía la pena cambiar basados en su uso y la frustración o satisfacción de la comunidad.

    En los últimos años se había evitado cambiar valores por defecto en un esfuerzo por contener la fricción durante actualizaciones de RuboCop. Pero con la publicación de una versión 1.0, llega la oportunidad de revisar esos valores. Con 722 respuestas, un número que hasta el autor admite es bastante decepcionante dada la cantidad de usuarios de la herramienta, finalmente se publicaron los resultados y cómo afectaría a RuboCop 1.0.

    Algunos de los resultados destacados:

    Comillas simples vs comillas dobles en Strings literales

    Personalmente uso comillas simples, y probablemente sea por costumbre de usar RuboCop y que me señala que tengo usar comillas simples cuando no estoy interpolando valores en un String. Hace unos años me acuerdo haber estudiado con Daniel Chains el tema respecto a la performance de simples contra dobles y vimos que no cambiaba nada. Pero como dice el autor del post original, lo único que importa es usar una o la otra de forma consistente. El resultado:

    • Comillas simples – 58%
    • Comillas dobles – 39%
    • Otro (por ejemplo “que no les importa”) – 3%

    Así que es algo que no va a cambiar por defecto, por más que sea uno de los temas en los cuales la comunidad parece ser más quejosa.

    Longitud máxima de caracteres por línea

    Acá estoy con la mayoría también. Si bien se puede configurar un Rubocop específico por proyecto, el valor por defecto de 80 caracteres me resultado demasiado corto.

    • 120 caracteres – 48%
    • 100 caracteres – 21%
    • 80 caracteres – 18%
    • Otro (ejemplo 150, sin límite) – 13%

    A pesar de cambiar el valor por defecto de RuboCop para líneas más largas, se agregó una nota en la Ruby Style Guide de por qué sigue siendo buena idea mantener líneas cortas.

    Comas finales en colecciones

    # sin comas:
    { uno: 1, dos: 2 }
    
    # con comas:
    { uno: 1, dos: 2, }
    

    El valor por defecto de no exigir comas al final ganó en los resultados, por lo que se mantiene igual:

    • No uso comas al final de la colección – 64%
    • Uso comas al final sólo en colecciones multi-línea- 27%
    • Uso comas al final en todos los casos- 1,5%
    • Otro – 7,5%

    and y or

    “La pregunta si and y or son útiles o deberían ser evitados completamente ha cautivado por mucho tiempo a la comunidad Ruby”. Acá también estoy con la mayoría, los usuarios de RuboCop dijeron:

    • No los uso para nada – 68%
    • Los uso todo el tiempo – 4%
    • Los uso para control de flujo (ejemplo do_something and return) – 29%

    A pesar de los resultados, decidieron ser más permisivos y permitirlos para control de flujo, más que nada porque es un estilo bastante común en Ruby On Rails.

    Doble Negación (!!)

    Resultados:

    • Solamente lo uso cuando necesito devolver un booleano – 53%
    • No lo uso para nada – 39%
    • Otro – 8%

    Así que la doble negación va a estar permitida en el contexto de return.

    Espacios dentro de los hash

    # con espacios
    { hulk: "Bruce Banner" }
    
    # sin espacios
    {hulk: "Bruce Banner"}
    

    En esta también sigo a la mayoría, 71% votaron que usan los espacios y 29% que no los usan.

    Paréntesis para argumentos de métodos de Kernel (puts, system, exit)

    # sin paréntesis
    puts "Hola, mundo!"
    exit -1
    
    # con paréntesis
    puts("Hola, mundo!")
    exit(-1)
    

    El 80% respondió que no usa paréntesis para estos métodos  y un 17% que sí usa paréntesis.

    ¿Encuentras los cops de métricas (como CyclomaticComplexity) útiles?

    • Un poco útiles – 43%
    • Muy útiles – 29%
    • Inútiles – 19%
    • Otro – 9%

    Los autores lo tomaron como un área donde se puede mejorar.

    Nivel general de felicidad con los valores por defecto de RuboCop

    • Muy feliz – 15%
    • Feliz – 47%
    • OK – 23%
    • No feliz – 8%
    • Muy infeliz – 5%

    Los resultados se ven como “no geniales, pero tampoco terribles”. Personalmente lo veo bastante bien, más de la mitad de los usuarios está al menos feliz. Con la versión 0.84 de RuboCop se hicieron cambios buscando mejorar estos resultados, y se van a venir más cambios

    Feedback General

    Al final de la encuesta había una sección abierta para más comentarios. Las respuestas resumidas:

    • El valor de varios cops es subjetivo y estaría bueno que RuboCop tuviera algún preset con cops realmente esenciales (como cops para Linting y los que se corresponden con las convenciones e idiomas más fuertes).
    • El valor de los cops de métricas es cuestionable. Hubo muchas sugerencias para relajar ciertos valores por defecto.
    • Mucha gente parece odiar los frozen string literals.

    El equipo planea trabajar en el primer punto y proveer un set más chico de cops esenciales, junto al actual set de cops por defecto en el futuro.

    Una nota aparte de Bozhidar Batsov, cuando vio mucha gente quejarse de los cops de métricas, agregó una pregunta extra para saber si la gente sabía que pueden deshabilitar departamentos enteros de cops a través de .rubocop.yml. El 40% de los usuarios no lo sabía, y se puede hacer con:

    Metrics:
      Enabled: true
    

    También si no me equivoco, podemos empezar un archivo rubocop.yml deshabilitando TODOS los cops, de manera de ir definiendo de a uno aquellos que nos interesan en el proyecto.

    El trabajo con esta encuesta y los cambios que ya vimos en RuboCop 0.84 muestran que el equipo de desarrollo está escuchando a la comunidad y ajustándose a las preferencias de la mayoría. La versión 1.0 está cerca, y avisan que es poco probable que haya más cambios de último momento, pero siempre existirá una versión 2.0 y 3.0.

    RuboCop es una excelente herramienta y creo que gran parte de la negatividad que se le atribuye viene de no definir conenciones a nivel de un equipo o quedarse con las convenciones por defecto que no se adaptan necesariamente a las preferencias de un grupo de usuarios. Pero es bastante fácil de personalizar, y lo importante al final del día es ser consistente, más allá de si usamos ' o " para definir Strings.

    Pueden leer más en RuboCop Defaults Survey Results.

    Viewing all 2699 articles
    Browse latest View live