phone

    • chevron_right

      Ignite Realtime Blog: Spark 3.0.2 Released

      news.movim.eu / PlanetJabber · Friday, 31 March, 2023 - 18:16 · 1 minute

    The Ignite Realtime community is happy to announce the availability of Spark version 3.0.2

    The release contains bug fixes and updates two plugins Translator and Roar.

    Many Spark translations are incomplete. Please help us translate Spark

    Full list of changes can be found in the changelog .

    We encourage users and developers to get involved with Spark project by providing feedback in the forums or submitting pull requests on our GitHub page.

    You can download Spark from the Downloads page. Below are the sha256 checksums:

    db7febafd05a064ffed4800066d11d0a2d27288aa3c0b174ed21a20672ab4669 *spark_3_0_2-64bit.exe
    647712b43942f7dc399901c9078ea1de7fcca14de3b5898bc3bdeee7751cf1b3 *spark_3_0_2-64bit.msi
    c1415417081095656c5fd7eb42e09ac6168f550af3c5254eb35506a404283a3c *spark_3_0_2-arm.exe
    78994eaa31d6c074bc72b9ac7a1f38f63488f9272c1a8870524f986dda618b6b *spark_3_0_2-with-jre.dmg
    ef3ba8eef5b88edc5e4ce9e13e9fa41ef2fad136cc6b518c52da79051c2a7c39 *spark_3_0_2-with-jre.exe
    d18dd7613333647f3fae6728731df7e3ef957103a84686ce1bb7befb9d32285f *spark_3_0_2-with-jre.msi
    39b03b4f4363bc053d2c5ed0c7452f97ced38a1c307ab77ce7f8b0e36459f498 *spark_3_0_2.deb
    5bc3bf000b4fe8a49d424ea53ccd6b62dae9291e987394f08c62ff0d69f0aec9 *spark_3_0_2.dmg
    e511c10db5f72e8b311f79dc3ac810040d44c5488f606cb860d7250d1dcf3709 *spark_3_0_2.exe
    f54d3990dd0ca76a1ca447af0bef9b4244861c7da9f6ab38a755c9cc578344c8 *spark_3_0_2.msi
    fff7fa157fe187b5307ef2383c87b8193a0416ffe41ffcb2ea0b0e6672a917f9 *spark_3_0_2.rpm
    a5cf06ccbe82dc308f2d2493bc0d89f552729fb993af392003263f0cd9caac16 *spark_3_0_2.sh
    03eae1e4e88fdc303752f3b5c0ef8bb00653cfdf28ee964699bba892e45110e4 *spark_3_0_2.tar.gz
    

    For other release announcements and news follow us on Twitter and Mastodon .

    1 post - 1 participant

    Read full topic

    • chevron_right

      Erlang Solutions: 5 Key Tech Priorities for Fintech Leaders in 2023

      news.movim.eu / PlanetJabber · Thursday, 30 March, 2023 - 10:09 · 6 minutes

    The fintech industry is a major disruptor. Each year, it impacts how consumers interact with financial companies and brings new and innovative means to meet ever-growing customer expectations and occupy market space.

    As a business owner or executive in this space, you have no choice but to stay on top of your game to increase efficiency.

    In simpler terms, if your business doesn’t scale, it could fail.

    That might sound a tad extreme, but you’re dealing in a market that is set to be worth $698.48 billion by 2030. Understanding the trends and focuses of the time helps you know where you’re headed in order to remain competitive.

    So let’s talk about these trends that drive the market.

    Embed finance

    The embedded finance market is expected to see massive growth this year. The market has been growing at a rapid pace since 2020. Fintech companies have been steadily outpacing traditional banking services when it comes to gaining the trust of consumers.

    According to our latest report , searches for the term have increased by a staggering 488% in the last five years.

    Embedded finance solutions can make up 50% of total banking revenue streams in the near future. There is also a significant market for embedded financial products in the areas of deposit accounts, payments, insurance, and lending.

    Source: Mckinsey analysis

    Arguably the greatest benefit to embedding finance is that under the direction of inclusive fintech startups, it has the potential to empower potential customers who were previously excluded from the conventional financial industry. Similarly, emerging markets can provide a less stifling environment with lower prices and a larger customer base, which would further encourage innovation.

    We’re also likely to see traditional financial services and fintech firms, such as banks and payment processors, collaborating more closely to adopt embedded finance. This could result in payment fintechs providing more inclusive services tailored to various business models, leasing more potential while banks provide fundamental infrastructure.

    Embedded finance solutions will place much greater emphasis on technological advantages and operational capability to address your business’s current issues. Think risk and compliance management. Innovations like distributed computing and artificial intelligence (AI) will have multiple effects across all businesses, strengthening their ability to embrace embedded finance.

    AI

    Financial institutions are continuing to adopt AI and machine learning, the industry is set to see a projected savings of up to 22% by the year 2030 .

    How is this possible? AI-driven chatbots and assistants can make the customer experience very efficient. They can answer customer questions, monitor spending and tailor product recommendations based directly on customer preferences.

    While chatbots do not quite replicate the human experience, their growth across the market this year means we can expect more of them in 2023.

    Source: Adobe

    Think about your price comparison sites when looking for insurance, or travel rates. These services have been made possible through the application of Natural Language Processing (NLP), which allows the ability to make payments and offer personalised service at any given time.

    A key element of AI technology is its ability to predict human interactions, combining the best of two words, intelligence and behavioural finance. What is Behavioural Finance? It focuses on human psychology to influence economic markets which in turn, impacts market outcomes. It is considered the future of fintech, as supported by the development of data analytics and large amounts of consumer data. This data, combined with AI algorithms, creates the ability to provide such personalised services.

    The industry is starting to recognize the goldmine that is AI. It doesn’t just drive efficiency but also makes allows businesses to be smarter in their approach to interacting with customers in the market.

    Blockchain

    Blockchain is one of the most exciting trends in Fintech today. It addresses the problem of unsecured, expensive fund transfer processes, with high-speed transactions at a much lower cost.

    It works as a digital ledger that verifies, records, and facilitates various types of transactions. Its major selling point is security and autonomy for customers, as businesses and individuals can safely transfer digital assets without relying on a central authority or financial institutions.

    But this isn’t just the only thing that appeals to users.

    Blockchain is used in various fintech applications, such as:

    • Decentralised finance (DeFi): Creates decentralised financial services- for example borrowing, health insurance, lending services etc
    • Digital assets: Provides a secure, transparent method of storing and trading digital assets- got example, NFTs and cryptocurrencies.
    • Cross-border payment services: Enable secure and fast cross-border payments
    • Supply chain management: Provides transparent and secure methods of tracking goods and assets within supply chain networks.
    • Identity management- Creates decentralised identity systems, offering increased security and privacy.

    As blockchain eliminates the need for traditional banking, it now makes it easier for customers to utilise these financial offerings. This is particularly significant for third-world and developing countries, where access to traditional banks can sometimes be challenging.

    Customer Experience

    We’ve spoken a lot about customer experience expectations already, but it is integral to the future of fintech services. After all, the focus will always be on the people your business serves.

    Banks that consistently optimise the customer experience are set to grow 3.2x faster than their competitors.

    It’s up to businesses to provide seamless, user-friendly experiences to attract and retain their customers. This means focusing investment on user-centred design, more personalised services and omnichannel support.

    Put yourselves in your customer’s shoes to understand their pain points, and use that data to create customised solutions that far exceed expectations.

    Sustainability and ESG

    Any forward-thinking businesses will have Environmental, Social and Corporate Governance (ESG) and sustainability at the heart of their plans this year.

    Customers, investors and employees alike are keen to see businesses contribute to making society more sustainable. And with a net-zero goal to be met by 2050 (in the UK), organisations across the globe are under much greater scrutiny to implement supporting policies.

    According to FIS Global , “ESG is top of mind for financial services firms globally, with 60% of executives saying they are developing new ESG products and services.”

    So if your business isn’t environmentally friendly, it might have an impact on your customer base. Brands that care about the planet and show strategic planning are the ones set to thrive. If you don’t care, expect your customers to find a business that does.

    This increased sustainability interest has led to a lot of financial institutions offering a diverse portfolio of sustainable options, such as loans backed by environmental enterprises, such as investment into wind or solar farms. ESG bonds are also rising in popularity.

    A trend we’ll see this year will be sustainable (green) financing. This is another way that financial regulations and products are orchestrated to meet environmentally sustainable outcomes.

    Green Financing will be a key Fintech trend that will aid the private sector in doing positive work for the environment. It will also encourage private-public alliances on financial mechanisms like green bonds.

    Looking ahead

    With the ongoing development of the Fintech industry, technological innovation must work in tandem with the economy’s call for greater financial inclusion.

    As firms across the globe embrace the potential of tech to champion the future, consider these trends and how (or if) your business is incorporating them.

    Want a more in-depth look into fintech themes and how they should inform your tech strategy and decision-making? You can download our latest whitepaper to hear from the experts.

    Our team are also on hand if you’d like a chat about your fintech project or any projects you might have. Don’t hesitate to contact us .

    The post 5 Key Tech Priorities for Fintech Leaders in 2023 appeared first on Erlang Solutions .

    • wifi_tethering open_in_new

      This post is public

      www.erlang-solutions.com /blog/5-key-tech-priorities-for-fintech-leaders-in-2023/

    • chevron_right

      Erlang Solutions: Cómo depurar tu RabbitMQ

      news.movim.eu / PlanetJabber · Wednesday, 29 March, 2023 - 11:08 · 14 minutes

    Descubre las herramientas y métodos adecuados para la depuración de RabbitMQ.

    Lo que aprenderás en este blog.

    Nuestros clientes de consultoría de RabbitMQ provienen de una amplia gama de industrias. Como resultado, hemos visto casi todos los comportamientos inesperados que puede presentar. RabbitMQ es un software complejo que emplea concurrencia y cómputo distribuido (a través de Erlang), por lo que depurarlo no siempre es sencillo. Para llegar a la causa raíz de un comportamiento inesperado (y no deseado), necesitas las herramientas adecuadas y la metodología adecuada. En este artículo, demostraremos ambas para ayudarte a aprender la técnica de depuración en RabbitMQ.

    El problema de depurar RabbitMQ.

    La inspiración para este blog proviene de un ejemplo real. Uno de nuestros clientes tenía la API HTTP de administración de RabbitMQ proporcionando información crucial a su sistema. El sistema dependía mucho de la API, específicamente del endpoint /api/queues  porque el sistema necesitaba saber el número de mensajes listos en cada cola en un clúster de RabbitMQ. El problema era que a veces una solicitud HTTP al endpoint duraba hasta decenas de segundos (en el peor de los casos, ni siquiera podían obtener una respuesta de la API).

    Entonces, ¿qué causó que algunas solicitudes tomaran tanto tiempo? Para responder a esa pregunta, intentamos reproducir el problema a través de pruebas de carga.

    Ejecutando pruebas de carga.

    Utilizamos una plataforma que creamos para MongooseIM para ejecutar nuestras Pruebas de Carga Continuas . Aquí están algunos de los aspectos más importantes de la plataforma:

    1. todos los servicios involucrados en una prueba de carga se ejecutan dentro de contenedores de docker
    2. la carga es generada por Amoc ; es una herramienta de código abierto escrita en Erlang para generar cargas masivamente paralelas de cualquier tipo (AMQP en nuestro caso)
    3. se recopilan métricas del sistema en prueba y del sitio de Amoc para un análisis posterior.

    El diagrama a continuación representa una arquitectura lógica de una prueba de carga de ejemplo con RabbitMQ:

    En el diagrama, el lado izquierdo muestra un clúster de nodos de Amoc que emulan clientes AMQP que, a su vez, generan la carga contra RabbitMQ. Por otro lado, podemos ver un clúster de RabbitMQ que sirve a los clientes AMQP. Todas las métricas de los servicios de Amoc y RabbitMQ se recopilan y almacenan en una base de datos InfluxDB.

    Consultas lentas de Management HTTP API

    Intentamos reproducir las consultas lentas a Management HTTP API en nuestras pruebas de carga. El escenario de prueba fue bastante sencillo. Un grupo de editores publicaba mensajes en el intercambio predeterminado. Los mensajes de cada editor se dirigían a una cola dedicada (cada editor tenía una cola dedicada). También había consumidores conectados a cada cola. La replicación de cola estaba habilitada.

    Para valores concretos, consulte la tabla a continuación:

    Esa configuración estresó los servidores Rabbit en nuestra infraestructura. Como se ve en los gráficos a continuación:

    Cada nodo de RabbitMQ consumió alrededor de 6 (de 7) núcleos de CPU y aproximadamente 1,4 GB de RAM, excepto rabbitmq-1 que consumió significativamente más que los otros. Eso se debió probablemente a que tuvo que atender más solicitudes de Management HTTP API que los otros dos nodos.

    Durante la prueba de carga, se consultó el endpoint /api/queues cada dos segundos para obtener la lista de todas las colas junto con los valores correspondientes de messages_ready . Una consulta se veía así:

    http://rabbitmq-1:15672/api/queues?columns=name,messages_ready

    Aquí están los resultados de la prueba:

    La figura anterior muestra el tiempo de consulta durante una prueba de carga. Está claro que las cosas son muy lentas. La mediana es de 1,5 segundos mientras que los percentiles 95, 99, 999 y máx. llegan a 20 segundos.

    Debugging

    Una vez confirmado el problema y puede reproducirse, estamos listos para comenzar a depurar. La primera idea fue encontrar la función Erlang que se llama cuando llega una solicitud a la API de administración HTTP de RabbitMQ y determinar dónde esa función pasa su tiempo de ejecución. Si pudiéramos hacer esto, nos permitiría localizar el código más costoso detrás de la API.

    Encontrar la función de entrada

    Para encontrar la función que estábamos buscando, tomamos los siguientes pasos:

    1. buscamos en el complemento de administración de RabbitMQ para encontrar la asignación adecuada de “ruta HTTP a función”,
    2. usamos la función de rastreo de Erlang para verificar si se llama a una función encontrada cuando llega una solicitud.

    El complemento de administración utiliza cowboy (un servidor HTTP de Erlang) debajo para servir las solicitudes de API. Cada punto final de HTTP requiere un módulo de devolución de llamada de cowboy, por lo que encontramos fácilmente la función rabbit_mgmt_wm_queues:to_json/2 que parecía manejar las solicitudes que llegaban a /api/queues. Confirmamos eso con el rastreo (usando una biblioteca de recuperación que se envía con RabbitMQ por defecto).

    root@rmq-test-rabbitmq-1:/rabbitmq_server-v3.7.9# erl -remsh rabbit@rmq-test-rabbitmq-1 -sname test2 -setcookie rabbit  
    Erlang/OTP 21 [erts-10.1] [source] [64-bit] [smp:22:7] [ds:22:7:10] [async-threads:1]  
    
    Eshell V10.1  (abort with ^G)  
    (rabbit@rmq-test-rabbitmq-1)1> recon_trace:calls({rabbit_mgmt_wm_queues, to_json, 2}, 1).  
    1  
    
    11:0:48.464423 <0.1294.15> rabbit_mgmt_wm_queues:to_json(#{bindings => #{},body_length => 0,cert => undefined,charset => undefined,  
      has_body => false,  
      headers =>  
          #{<<"accept">> => <<"*/*">>,  
            <<"authorization">> => <<"Basic Z3Vlc3Q6Z3Vlc3Q=">>,  
            <<"host">> => <<"10.100.10.140:53553">>,  
            <<"user-agent">> => <<"curl/7.54.0">>},  
      host => <<"10.100.10.140">>,host_info => undefined,  
      media_type => {<<"application">>,<<"json">>,[]},  
      method => <<"GET">>,path => <<"/api/queues">>,path_info => undefined,  
      peer => {{10,100,10,4},54136},  
      pid => <0.1293.15>,port => 53553,qs => <<"columns=name,messages_ready">>,  
      ref => rabbit_web_dispatch_sup_15672,  
      resp_headers =>  
          #{<<"content-security-policy">> => <<"default-src 'self'">>,  
            <<"content-type">> => [<<"application">>,<<"/">>,<<"json">>,<<>>],  
            <<"vary">> =>  
                [<<"accept">>,  
                 [<<", ">>,<<"accept-encoding">>],  
                 [<<", ">>,<<"origin">>]]},  
      scheme => <<"http">>,  
      sock => {{172,17,0,4},15672},  
      streamid => 1,version => 'HTTP/1.1'}, {context,{user,<<"guest">>,  
                   [administrator],  
                   [{rabbit_auth_backend_internal,none}]},  
             <<"guest">>,undefined})  
    Recon tracer rate limit tripped. 
    

    El fragmento anterior muestra que primero habilitamos el seguimiento para rabbit_mgmt_wm_queues:to_json/2 , luego enviamos manualmente una solicitud a la API de administración (usando curl; no visible en el fragmento) y que generó el evento de seguimiento. Así es como encontramos nuestro punto de entrada para un análisis más profundo.

    Usando flame graphs

    Una vez que hemos encontrado una función que sirve las solicitudes, ahora podemos verificar cómo esa función pasa su tiempo de ejecución. La técnica ideal para hacer esto es Flame Graphs. Una de sus definiciones establece que:

    Los gráficos de llamas son una visualización del software perfilado, lo que permite identificar rápidamente y con precisión los caminos de código más frecuentes.

    En nuestro caso, podríamos usar gráficos de llamas para visualizar la pila de llamadas de la función o, en otras palabras, qué funciones se llaman dentro de una función rastreada y cuánto tiempo tarda (en relación con el tiempo de ejecución de la función rastreada) para que estas funciones se ejecuten. Esta visualización ayuda a identificar rápidamente las funciones sospechosas en el código.

    Para Erlang, existe una biblioteca llamada eflame que tiene herramientas tanto para: recopilar trazas del sistema Erlang como para construir un gráfico de llamas a partir de los datos. ¿Pero cómo inyectamos esa biblioteca en Rabbit para nuestra prueba de carga?

    Construyendo una imagen personalizada de Docker para RabbitMQ

    Como mencionamos anteriormente, todos los servicios de nuestra plataforma de pruebas de carga se ejecutan dentro de contenedores Docker. Por lo tanto, tuvimos que construir una imagen personalizada de Docker para RabbitMQ con la biblioteca eflame incluida en el código del servidor. Creamos un repositorio de RabbitMQ-docker que hace que sea fácil construir una imagen de Docker con el código fuente de RabbitMQ modificado.

    Perfilando con eflame

    Una vez que tuvimos una imagen de Docker de RabbitMQ modificada con eflame incluido, pudimos ejecutar otra prueba de carga (las especificaciones eran las mismas que en la prueba anterior) y comenzar el perfilado real. Estos fueron los resultados:

    Realizamos varias mediciones y obtuvimos dos tipos de resultados como se presentan arriba. La principal diferencia entre estos gráficos se encuentra en la función rabbit_mgmt_util:run_run_augmentation/2 . ¿Qué significa esa diferencia?

    A partir de los resultados de las pruebas de carga anteriores y del análisis manual del código, sabemos que existen consultas lentas y rápidas. Las solicitudes lentas pueden tardar hasta veinte segundos, mientras que las rápidas solo tardan unos pocos segundos. Esto confirma el gráfico de tiempo de consulta anterior con un percentil del 50 de alrededor de 1,5 segundos, pero el 95 (y porcentajes más altos) que llegan hasta 20 segundos. Además, medimos manualmente el tiempo de ejecución de ambos casos utilizando timer:tc/3 y los resultados fueron consistentes.

    Esto sucede porque hay una caché en el plugin de Management. Cuando la caché es válida, las solicitudes se sirven mucho más rápido ya que los datos ya se han recopilado, pero cuando es inválida, es necesario recopilar toda la información necesaria.

    A pesar de que los gráficos tienen la misma longitud en la imagen, representan diferentes tiempos de ejecución (rápido vs lento). Por lo tanto, es difícil adivinar qué gráfico muestra qué consulta sin tomar realmente una medición. El primer gráfico muestra una consulta rápida mientras que el segundo muestra una consulta lenta. En el gráfico de consulta lenta rabbit_mgmt_util:augment/2 -> rabbit_mgmt_db:submit_cached/4 -> gen_server:call/3 -> … la pila tarda tanto tiempo porque la caché es inválida y se necesita recopilar datos nuevos. Entonces, ¿qué sucede cuando se recopilan los datos?

    Perfiles con fprof

    Podrías preguntar: “¿por qué no vemos las funciones de recopilación de datos en los gráficos de llama?” Esto sucede porque la caché se implementa como otro proceso de Erlang y la recopilación de datos ocurre dentro del proceso de caché. Hay una función gen_server:call/3 visible en los gráficos que hace una llamada al proceso de caché y espera una respuesta. Dependiendo del estado de la caché (válido o inválido), una respuesta puede volver rápidamente o lentamente.

    La recopilación de datos se implementa en la función rabbit_mgmt_db:list_queue_stats/3 que se invoca desde el proceso de caché. Naturalmente, deberíamos perfilar esa función. Probamos con eflame y después de varias docenas de minutos , este es el resultado que obtuvimos:

    eheap_alloc: Cannot allocate 42116020480 bytes of memory (of type "old_heap").
    

    El asignador de memoria del montón de Erlang intentó asignar 42 GB de memoria (de hecho, se necesitaba espacio para que el recolector de basura operara) y se bloqueó el servidor. Como eflame aprovecha el seguimiento de Erlang para generar gráficos de llama, probablemente se sobrecargó con la cantidad de eventos de seguimiento generados por la función rastreada. Ahí es donde entra en juego fprof.

    Según la documentación oficial de Erlang, fprof es:

    una herramienta de perfilado de tiempo que utiliza el seguimiento de archivo para un impacto mínimo en el rendimiento en tiempo de ejecución.

    Esto es muy cierto. La herramienta manejó la función de recopilación de datos sin problemas, aunque tardó varios minutos en producir el resultado. La salida fue bastante grande, así que solo se enumeran las líneas cruciales a continuación:

    (rabbit@rmq-test-rabbitmq-1)96> fprof:apply(rabbit_mgmt_db, list_queue_stats, [RA, B, 5000]).  
    ...
    (rabbit@rmq-test-rabbitmq-1)97> fprof:profile().  
    ...
    (rabbit@rmq-test-rabbitmq-1)98> fprof:analyse().  
    ...
    %                                       CNT        ACC       OWN  
    {[{{rabbit_mgmt_db,'-list_queue_stats/3-lc$^1/1-1-',4}, 803,391175.593,  105.666}],  
     { {rabbit_mgmt_db,queue_stats,3},              803,391175.593,  105.666},     %  
     [{{rabbit_mgmt_db,format_range,4},            3212,390985.427,   76.758},  
      {{rabbit_mgmt_db,pick_range,2},              3212,   58.047,   34.206},  
      {{erlang,'++',2},                            2407,   19.445,   19.445},  
      {{rabbit_mgmt_db,message_stats,1},            803,    7.040,    7.040}]}.  
    

    El resultado consiste en muchas de estas entradas. La función marcada con el carácter % es la que concierne a la entrada actual. Las funciones que se encuentran debajo son las que se llamaron desde la función marcada. La tercera columna ( ACC ) muestra el tiempo de ejecución total de la función marcada (tiempo de ejecución propio de la función y de los que la llaman) en milisegundos. Por ejemplo, en la entrada anterior, el tiempo de ejecución total de la función rabbit_mgmt_db:pick_range/2 es de 58.047 ms. Para obtener una explicación detallada de la salida de fprof, consulte la documentación oficial de fprof.

    La entrada anterior es la entrada de nivel superior que concierne a rabbit_mgmt_db:queue_stats/3 , que se llamó desde la función rastreada. Esa función gastó la mayor parte de su tiempo de ejecución en la función rabbit_mgmt_db:format_range/4. Podemos ir a una entrada que concierna a esa función y comprobar en qué gastó su tiempo de ejecución. De esta manera, podemos revisar la salida y encontrar posibles causas del problema de lentitud de la API de gestión.

    Al leer la salida de fprof de arriba hacia abajo, llegamos a esta entrada:

    {[{{exometer_slide,'-sum/5-anonymous-6-',7},   3713,364774.737,  206.874}],
     { {exometer_slide,to_normalized_list,6},      3713,364774.737,  206.874},     %
     [{{exometer_slide,create_normalized_lookup,4},3713,213922.287,   64.599}, %% SUSPICIOUS
      {{exometer_slide,'-to_normalized_list/6-lists^foldl/2-4-',3},3713,145165.626,   51.991}, %% SUSPICIOUS
      {{exometer_slide,to_list_from,3},            3713, 4518.772,  201.682},
      {{lists,seq,3},                              3713,  837.788,   35.720},
      {{erlang,'++',2},                            3712,   70.038,   70.038},
      {{exometer_slide,'-sum/5-anonymous-5-',1},   3713,   51.971,   25.739},
      {garbage_collect,                               1,    1.269,    1.269},
      {suspend,                                       2,    0.151,    0.000}]}.  
    

    La entrada se refiere a la función exometer_slide:to_normalized_list/6 que a su vez llamó a dos funciones “sospechosas” del mismo módulo. Profundizando encontramos esto:

    {[{{exometer_slide,'-create_normalized_lookup/4-anonymous-2-',5},347962,196916.209,35453.182},
      {{exometer_slide,'-sum/5-anonymous-4-',2},   356109,16625.240, 4471.993},
      {{orddict,update,4},                         20268881,    0.000,172352.980}],
     { {orddict,update,4},                         20972952,213541.449,212278.155},     %
     [{suspend,                                    9301,  682.033,    0.000},
      {{exometer_slide,'-sum/5-anonymous-3-',2},   31204,  420.574,  227.727},
      {garbage_collect,                              99,  160.687,  160.687},
      {{orddict,update,4},                         20268881,    0.000,172352.980}]}. 
    

    and

       {[{{exometer_slide,'-to_normalized_list/6-anonymous-5-',3},456669,133229.862, 3043.145},
      {{orddict,find,2},                           19369215,    0.000,129761.708}],
     { {orddict,find,2},                           19825884,133229.862,132804.853},     %
     [{suspend,                                    4754,  392.064,    0.000},
      {garbage_collect,                              22,   33.195,   33.195},
      {{orddict,find,2},                           19369215,    0.000,129761.708}]}.  
    

    Gran parte del tiempo de ejecución fue consumido por las funciones orddict:update/4 y orddict:find/2 . Ambas funciones combinadas representaron el 86% del tiempo total de ejecución.

    Esto nos llevó al módulo exometer_slide del plugin RabbitMQ Management Agent. Si se examina el módulo, se encontrarán todas las funciones mencionadas y las conexiones entre ellas.

    Decidimos cerrar la investigación en esta etapa porque este era claramente el problema. Ahora que hemos compartido nuestras reflexiones sobre el problema con la comunidad en este blog, quién sabe, tal vez encontraremos una nueva solución juntos.

    El efecto observador

    Hay una última cosa que es esencial considerar cuando se trata de depurar/observar sistemas: el efecto observador. El efecto observador es una teoría que afirma que si estamos monitoreando algún tipo de fenómeno, el proceso de observación cambia ese fenómeno.

    En nuestro ejemplo, utilizamos herramientas que se aprovechan del rastreo. El rastreo tiene un impacto en un sistema ya que genera, envía y procesa muchos eventos.

    Los tiempos de ejecución de las funciones mencionadas anteriormente aumentaron considerablemente cuando se llamaron con el perfilado habilitado. Las llamadas puras tomaron varios segundos mientras que las llamadas con el perfilado habilitado tomaron varios minutos. Sin embargo, la diferencia entre las consultas lentas y rápidas pareció permanecer sin cambios.

    El efecto observador no fue evaluado en el alcance del experimento descrito en esta publicación de blog.

    Una solución alternativa

    El problema puede ser resuelto de una manera ligeramente diferente. Pensemos por un momento si hay otra manera de obtener los nombres de las colas correspondientes a la cantidad de mensajes en ellas. Existe la función rabbit_amqqueue:emit_info_all/5 que nos permite recuperar la información exacta que nos interesa, directamente desde un proceso de cola. Podríamos utilizar esa API desde un plugin personalizado de RabbitMQ y exponer un punto final HTTP para enviar esos datos cuando se consulten.

    Convertimos esa idea en realidad y construimos un plugin de prueba de concepto llamado rabbitmq-queue-info que hace exactamente lo que se describe arriba. Incluso se realizó una prueba de carga del plugin (la especificación de la prueba fue exactamente la misma que la del plugin de gestión, como se mencionó anteriormente en el blog). Los resultados se muestran a continuación y hablan por sí solos:

    ¿Quieren más?

    ¿Quiere saber más sobre el rastreo en RabbitMQ, Erlang y Elixir? Consulte WombatOAM, un sistema intuitivo que facilita la supervisión y el mantenimiento de sus sistemas. Obtenga su prueba gratuita de 45 días de WombatOAM ahora.

    Apéndice

    La versión 3.7.9 de RabbitMQ se utilizó en todas las pruebas de carga mencionadas en esta publicación de blog. Un agradecimiento especial a Szymon Mentel y Andrzej Teleżyński por toda la ayuda con esa publicación.

    Nuestro trabajo con RabbitMQ.

    The post Cómo depurar tu RabbitMQ appeared first on Erlang Solutions .

    • chevron_right

      Ignite Realtime Blog: Release v1.1.0 of the MUC Real-Time Block List plugin for Openfire

      news.movim.eu / PlanetJabber · Saturday, 18 March, 2023 - 10:00 · 1 minute

    We are happy to announce the immediate availability of a new version of the MUC Real-Time Block List plugin for Openfire , our cross-platform real-time collaboration server based on the XMPP protocol! This plugin can help you moderate your chat rooms, especially when your service is part of a larger network of federated XMPP domains.

    From experience, the XMPP community has learned that bad actors tend to spam a wide range of public chat rooms on an equally wide range of different domains. Prior to the functionality provided by this plugin, the administrator of each MUC service had to manually adjust permissions, to keep unwanted entities out. With this new plugin, that process is automated.

    In this new release, several small bugs were fixed, and new features were introduced, including:

    • The plugin now, by default, uses a block list as maintained on https://xmppbl.org/
    • Support for blocking full domains (rather than just individual users) has been added
    • Block list entries no longer disappear over time

    The updated plugin should become available for download in your Openfire admin console in the course of the next few hours. Alternatively, you can download the plugin directly, from the plugin’s archive page .

    For other release announcements and news follow us on Twitter and Mastodon .

    1 post - 1 participant

    Read full topic

    • wifi_tethering open_in_new

      This post is public

      discourse.igniterealtime.org /t/release-v1-1-0-of-the-muc-real-time-block-list-plugin-for-openfire/92673

    • chevron_right

      Erlang Solutions: Here’s Why You Should Build Scalable Systems with Erlang

      news.movim.eu / PlanetJabber · Thursday, 16 March, 2023 - 10:00 · 5 minutes

    Building systems in the earlier days of the internet used to be pretty simple.

    While the system was admittedly pretty limited, the demand to scale past one or two servers wasn’t particularly high. But upon entering the 21st century, we saw large companies (think Amazon, Starbucks, Yahoo) and many more find the need to scale not just a few servers, but thousands. Even tens of thousands. Suddenly, the old-school system was impractical and nearly impossible to scale past one of two servers.

    The need for a system that offers scalability, flexibility and resilience had arrived. Enter Erlang- the powerful programming language designed for building highly scalable, fault-tolerant systems.

    Wondering what benefits there are to a scalable system like Erlang? Keep reading. We’ll be breaking down those very basics in this blog.

    A bit of background on Erlang

    But first, a bit of history of the Erlang language.

    Erlang was developed in the 1980s by Ericsson. Since then, it has been used to build large-scale distributed systems, such as telecom switching systems, online gaming platforms, and social networking sites.

    So, what is a scalable system?

    Before we start discussing scalable systems , let’s see what is really meant by the term ‘scaleable’.

    Measuring scalability is the ability to measure a system’s ability to increase or decrease in cost and performance, in response to the changes in a system’s demands.

    Now, it may seem obvious that an application being used by one user would require different levels of technology than one being used by a hundred. Yet, the reality is that there are still many businesses using technology that does not allow for this flexibility. This often leads to companies having to invest more money in creating software from scratch whenever they grow.

    As digital transformation drives accelerated business growth, businesses of all sizes need to be able to scale operations and adapt to their rapidly changing environments quickly. It’s no surprise that scalability has become an increasingly important factor when dealing with developing applications. Businesses have no choice but to be scalable, or they will face becoming overwhelmed when usage increases and will eventually become unable to meet the demands of a growing user base.

    A scalable computer language such as Erlang can write large new programmes and extend large existing ones relatively pain-free, depending on the complexity of the size of the programme it is trying to manage.

    Concurrency and parallelism in Erlang

    Erlang does a lot of things differently, one of those things being concurrency. When compared to most other programming languages that treat concurrency as an afterthought, Erlang builds in concurrency from the very base of the system.

    It was designed from the ground up to support concurrency and parallelism.

    Illustrating concurrency and parallelism on a 2-core CPU. Source: OpenClassrooms 2020. https://devopedia.org/concurrency-vs-parallelism

    Erlang’s lightweight processes, also known as actors, can execute in parallel, and they communicate with each other by exchanging messages. This message-passing model makes it easy to build highly concurrent systems that can handle a large number of users.

    Fault tolerance (Let it Crash)

    The philosophy behind Erlang is simply ‘Let it Crash.’

    Sound odd, right? Actually, letting it crash isn’t about crashing for the user or system.

    It’s about containing failure and letting Erlang clean it up.

    It knows that errors will happen, and things will break.

    Instead of trying to simply guard against those errors, Erlang has a built-in mechanism to handle those errors and failures.

    These mechanisms allow guarding against errors. So when a process crashes, it can restart automatically. In turn, the system restarts quickly and continues to operate smoothly.

    OTP

    The Open Telecom Platform (OTP) is a set of tools, frameworks and principles that are designed to guide and support the deployment of Erlang systems.

    OTP includes a wide range of components, such as a supervision tree, process registry, and message queues, which can be used to build complex distributed systems.

    Supervision tree example https://www.erlang.org/doc/design_principles/des_princ.htm

    Focusing on the supervision tree is a key hierarchical structuring model that is based on the idea of workers and supervisors, which makes it possible to design and programme fault-tolerant software.

    The workers are processes that perform computations meaning, they do the actual work. And supervisors are processes that monitor the behaviour of those workers. A supervisor can restart a worker if something goes wrong.

    Using OTP in your projects will help you to avoid accidental complexity.

    Distributed systems

    Erlang was designed for building distributed systems. It has built-in support for building systems that span multiple nodes. Erlang’s distribution mechanism allows processes to communicate with each other across the network, making it simple to build systems that scale horizontally.

    Erlang is high- performance

    Erlang is an incredibly high-performing language that can handle a large number of concurrent users and has great resilience over high task loads.

    Well known for its low latency, it is well-suited for building systems that require real-time processing and also has a small memory footprint, which enables it to run efficiently on low-end hardware.

    Hot Code Loading

    Erlang has a unique feature known as hot code loading, which enables developers to update their systems without shutting them down.

    Another way to think of it is that Hot Code Loading is the art of replacing an engine from a running car, without ever having to stop the car itself. It can update the code without causing any disruption to the service, meaning zero impact on users.

    This feature is particularly useful for building systems that need to be available 24/7.

    Scalability

    Last but not least, Erlang’s scalability is next to none. This language can be used to build systems that can handle millions of users. Erlang’s concurrency model and distributed architecture make it easy to build systems that can scale horizontally across multiple nodes, allowing developers to handle increasing loads, without sacrificing performance.

    To conclude

    Overall, Erlang is a great choice for building large-scale distributed systems that need to be highly available and performant. It handles concurrency and all its complexities with robustness and ease. But don’t just take our word for it. There are thousands of companies across the globe that have enlisted Erlang beyond its early days in telecoms.

    But don’t just take our word for it. Here are some of the clients who have felt the real-life impact of Erlang on their businesses .

    Fancy finding more out about Erlang? Check out our page .

    The post Here’s Why You Should Build Scalable Systems with Erlang appeared first on Erlang Solutions .

    • wifi_tethering open_in_new

      This post is public

      www.erlang-solutions.com /blog/heres-why-you-should-build-scalable-systems-with-erlang/

    • chevron_right

      Ignite Realtime Blog: Developing Openfire Efficient XML Interchange (EXI) functionality

      news.movim.eu / PlanetJabber · Tuesday, 14 March, 2023 - 19:39 · 1 minute

    We am excited to announce that a new plugin for the Openfire real time collaboration server is in the works! This plugin implements Efficient XML Interchange (EXI) functionality and provides an XMPP implementation of EXI as defined in XEP-0322 .

    Efficient XML Interchange (EXI) is a binary XML format for exchange of data on a computer network. It is one of the most prominent efforts to encode XML documents in a binary data format, rather than plain text. Using EXI format reduces the verbosity of XML documents as well as the cost of parsing.

    EXI is useful for:

    • a complete range of XML document sizes, from dozens of bytes to terabytes
    • reducing computational overhead to speed up parsing of compressed documents
    • increasing endurance of small devices by utilizing efficient decompression

    Read more about EXI in its Wikipedia article (where the above definition was taken from).

    The plugin that we’re developing today was first created by Javier Placencio, in 2013 and 2014. In 2023, that now dormant project was forked by the Ignite Realtime community.

    Work on the plugin is progressing steadily. Most of the core functionality is believed to be ready. In preparation for the official release of the plugin, we are looking for opportunities to perform interoperability testing. So far, testing has been done with our own mock client implementations. To be able to release a fully functional plugin, we’d like to test against implementations of other authors. Development builds of the plugin can be downloaded from the Openfire EXI plugin archive page .

    Are you interested in this? Please reach out to us on the Ignite Realtime Community , or stop by the open chat ! We would love to hear from you!

    For other release announcements and news follow us on Twitter and Mastodon .

    1 post - 1 participant

    Read full topic

    • wifi_tethering open_in_new

      This post is public

      discourse.igniterealtime.org /t/developing-openfire-efficient-xml-interchange-exi-functionality/92663

    • chevron_right

      Erlang Solutions: Presentamos el soporte de transmisión en RabbitMQ

      news.movim.eu / PlanetJabber · Monday, 13 March, 2023 - 19:33 · 11 minutes

    ¿Quiere saber más sobre el soporte de transmisión en RabbitMQ? Arnaud Cogoluègnes, ingeniero de personal de VMware, desglosa todo lo que hay que saber en la Cumbre RabbitMQ de 2021.

    En julio de 2021, se introdujeron streams a RabbitMQ, utilizando un nuevo protocolo extremadamente rápido que se puede utilizar junto con AMQP 0.9.1. Los streams ofrecen una forma más fácil de resolver varios problemas en RabbitMQ, incluyendo grandes fan-outs, replay y time travel, y grandes logs, todo con un rendimiento muy alto (1 millón de mensajes por segundo en un clúster de 3 nodos). Arnaud Cogoluègnes , Ingeniero de Staff en VMware , presentó los streams y cómo se utilizan mejor.

    Esta charla fue grabada en el RabbitMQ Summit 2021. La 4ta edición del RabbitMQ Summit se llevará a cabo como un evento híbrido, tanto en persona (en el lugar CodeNode en Londres) como virtual, el 16 de septiembre de 2022 y reunirá a algunas de las mayores empresas del mundo que utilizan RabbitMQ, todas en un solo lugar.

    Streams: Un Nuevo Tipo de Estructura de Datos en RabbitMQ

    Streams son una nueva estructura de datos en RabbitMQ que abren un mundo de posibilidades para nuevos casos de uso. Modelan un registro de solo agregado, lo que representa un gran cambio respecto a las colas tradicionales de RabbitMQ, ya que tienen semántica de consumidor no destructiva. Esto significa que cuando se leen mensajes de un Stream, no se eliminan, mientras que en las colas, cuando se lee un mensaje de una cola, se destruye. Este comportamiento reutilizable de RabbitMQ Streams se facilita mediante la estructura de registro de solo agregado.

    Text from the image:(Streams: a un nuevo tipo de estructura de datos en RabbitMQ)
    (Modela registros de solo anexar) (Persistente y replicado)(semántica de cliente no destructiva)(AMQP 0.9.1 y protocolo nuevo)

    RabbitMQ también introdujo un nuevo protocolo, el protocolo Stream, que permite un flujo de mensajes mucho más rápido. Sin embargo, también puedes acceder a Streams a través del protocolo AMQP 0.9.1 tradicional, que sigue siendo el protocolo más utilizado en RabbitMQ. También son accesibles a través de otros protocolos que RabbitMQ soporta, como MQTT y STOMP.

    Fortalezas de Streams

    Los Streams tienen fortalezas únicas que les permiten destacar en algunos casos de uso. Estas incluyen:

    Difusión masiva

    Cuando tienes varias aplicaciones en tu sistema que necesitan leer los mismos mensajes, tienes una arquitectura de difusión masiva. Los Streams son excelentes para las difusiones masivas, gracias a sus semánticas de consumo no destructivas, eliminando la necesidad de copiar el mensaje dentro de RabbitMQ tantas veces como haya consumidores.

    Reproducción y viaje en el tiempo

    Los Streams también ofrecen capacidades de reproducción y viaje en el tiempo. Los consumidores pueden adjuntarse en cualquier lugar de un Stream, utilizando un desplazamiento absoluto o una marca de tiempo, y pueden leer y volver a leer los mismos datos tantas veces como sea necesario.

    Rendimiento

    Gracias al nuevo protocolo de stream, los streams tienen el potencial de ser significativamente más rápidos que las colas tradicionales. Si necesitas un alto rendimiento o estás trabajando con mensajes grandes, los streams a menudo pueden ser una opción adecuada.

    Mensajes grandes

    Los Streams también son buenos para grandes registros. Los mensajes en los streams siempre son persistentes en el sistema de archivos, y los mensajes no permanecen en la memoria por mucho tiempo. Al consumirse, se utiliza la caché de archivos del sistema operativo para permitir un flujo de mensajes rápido.

    RabbitMQ also introduced a new protocol, the Stream protocol, which allows much faster message flow, however, you can access Streams through the traditional AMQP 0.9.1 protocol as well, which remains the most used protocol in RabbitMQ. They are also accessible through the other protocols that RabbitMQ supports, such as MQTT and STOMP.

    Text from the image:(Grandes fan-outs) (Repetición/tiempo de viaje)(Alto rendimiento)(Grandes registros)

    La Abstracción del Log

    Un stream es inmutable, puedes añadir mensajes, pero una vez que un mensaje ha entrado en el stream, no se puede eliminar. Esto hace que la abstracción del log del stream sea una estructura de datos bastante simple en comparación con las colas donde los mensajes siempre se añaden y se eliminan. Esto nos lleva a otro concepto importante, el offset. El offset es simplemente un índice técnico de un mensaje dentro del stream, o una marca de tiempo. Los consumidores pueden indicar a RabbitMQ que empiece a leer desde un offset en lugar del principio del stream. Esto permite una fácil reproducción y viaje en el tiempo de los mensajes. Los consumidores también pueden delegar la responsabilidad de seguimiento del offset a RabbitMQ.

    Text from the image:
    (La abstracción de registros)
    (Un modelo de secuencias y un registro de solo anexar)

    (Estructura de datos FIFO)
    (Lectura no destructiva)

    (Mensaje más viejo) (Compensar)(Último mensaje)(Proximo mensaje iría aquí en su lugar)

    Podemos tener cualquier cantidad de consumidores en un stream, no compiten entre sí, una aplicación consumidora no robará mensajes de otras aplicaciones, y la misma aplicación puede leer el flujo de mensajes muchas veces.

    Las colas pueden almacenar mensajes en memoria o en disco, pueden estar en un solo nodo o estar replicadas, los streams son persistentes y replicados en todo momento. Cuando creamos un stream, tendrá un líder ubicado en un nodo y réplicas en otros nodos. Las réplicas seguirán al líder y sincronizarán los datos. El líder es el único que puede crear operaciones de escritura y las réplicas solo se utilizarán para servir a los consumidores.

    Colas de RabbitMQ vs. Streams

    Los streams están aquí para complementar las colas y ampliar los casos de uso de RabbitMQ. Las colas tradicionales siguen siendo la mejor herramienta para los casos de uso más comunes en RabbitMQ, pero tienen sus limitaciones, hay momentos en los que no son la mejor opción.

    Los streams son, al igual que las colas, una estructura de datos FIFO, es decir, el mensaje más antiguo publicado se leerá primero. Proporcionar un desplazamiento permite al cliente omitir el comienzo del flujo, pero los mensajes se leerán en el orden de publicación.

    En RabbitMQ, tiene una cola tradicional con un par de mensajes y una aplicación consumidora. Después de registrar el consumidor, el intermediario comenzará a despachar mensajes al cliente y la aplicación puede comenzar a procesarlos.

    Cuando, en este punto, el mensaje está en un punto importante de su vida útil, está presente en el lado del remitente y también en el lado del consumidor. El intermediario todavía necesita preocuparse por el mensaje porque puede ser rechazado y debe saber que aún no se ha reconocido. Después de que la aplicación termine de procesar el mensaje, puede reconocerlo y, a partir de este momento, el intermediario puede deshacerse del mensaje y considerarlo procesado. Esto es lo que podemos llamar consumo destructivo, y es el comportamiento de las colas clásicas y de cuórum. Al usar Streams, el mensaje permanece en el Stream mientras la política de retención lo permita.

    Implementar configuraciones de gran difusión masiva con RabbitMQ no era óptimo antes de Streams. Cuando entra un mensaje, va a un intercambio y se enruta a una cola. Si desea que otra aplicación procese los mensajes, debe crear una nueva cola, vincular la cola al intercambio y comenzar a consumir. Este proceso crea una copia del mensaje para cada aplicación, y si necesita que otra aplicación procese los mismos mensajes, debe repetir el proceso; entonces otra cola, un nuevo enlace, un nuevo consumidor y una nueva copia del mensaje.

    Este método funciona y se ha utilizado durante años, pero no escala de manera elegante cuando se tienen muchas aplicaciones consumidoras. Los streams proporcionan una mejor manera de implementar esto, ya que los mensajes pueden ser leídos por cada consumidor por separado, en orden, desde el Stream.

    Rendimiento de los streams de RabbitMQ usando AMQP y el protocolo de Stream

    Como se explica en la charla, hubo un mayor rendimiento con Streams en comparación con las colas de cuórum.

    Obtuvieron alrededor de 40,000 mensajes por segundo con las Colas Quórum y 64,000 mensajes por segundo con Streams. Esto se debe a que Streams son una estructura de datos más simple que las Colas Quórum, ya que no tienen que lidiar con cosas complicadas como la confirmación de mensajes, mensajes rechazados o reencolado.

    Text from the image:
    (Streams en AMQP)
    (Cluster de 3 nodos (instancias c2-standard-16))
    (Tarifas de publicación)
    (mensajes/segundos)

    (Colas Quorum)(Stream en AMQP)

    Las colas de Quorum siguen siendo colas replicadas y persistentes de vanguardia, mientras que las Streams son para otros casos de uso. Al usar el protocolo Stream dedicado, se pueden lograr tasas de transferencia de un millón de mensajes por segundo.

    Text from the image: (Protocolo Stream)
    (Cluster de 3 nodos (instancias c2-standard-16))
    (Tarifas de publicación)
    (mensajes/segundos)
    (Colas Quorum)
    (Stream en AMQP)
    (Stream con protocolo de stream)

    El Protocolo Stream ha sido diseñado teniendo en cuenta el rendimiento y utiliza técnicas de bajo nivel como la API libC sendfile, la caché de página del sistema operativo y el agrupamiento, lo que lo hace más rápido que las colas AMQP.

    El plugin RabbitMQ Stream y los clientes

    Los Streams están disponibles a través de un nuevo plugin en la distribución principal. Cuando está activado, RabbitMQ comenzará a escuchar en un nuevo puerto que puede ser utilizado por los clientes que comprenden el Protocolo Stream. Está integrado con la infraestructura existente en RabbitMQ, como la interfaz de gestión, la API REST y Prometheus.

    Text from the image: (Los Streams son también accesibles a través de un nuevo protocolo)
    (Rápido) (Complemento en la distribución principal)(integración de gestión)

    Hay un cliente dedicado en Java y Go que utiliza este nuevo protocolo de flujo. El cliente de Java es la implementación de referencia. También está disponible una herramienta de prueba de rendimiento. Los clientes para otros lenguajes también son desarrollados activamente por la comunidad y el equipo central.

    El protocolo de flujo es un poco más simple que AMQP; no hay enrutamiento; simplemente se publica en un flujo, no hay intercambio involucrado, y se consume de un flujo como de una cola. No se necesita lógica para decidir dónde se debe dirigir el mensaje. Cuando publicas un mensaje desde tus aplicaciones cliente, este va a la red y casi directamente al almacenamiento.

    Existe una excelente interoperabilidad entre los flujos y el resto de RabbitMQ. Los mensajes se pueden consumir desde una aplicación cliente AMQP 0.9.1 y también funciona en sentido contrario.

    Ejemplo de caso de uso para interoperabilidad:

    Las colas y los flujos viven en el mismo espacio de nombres en RabbitMQ, por lo que se puede especificar el nombre del flujo del que se desea consumir utilizando los clientes AMQP habituales y mediante el parámetro x-stream-offset para basicConsume.

    Es muy fácil publicar con clientes AMQP porque es lo mismo que con las colas, se publica en un intercambio.

    Text from the image: (Agregar Stream para Analiticas)
    (Editor)(Cola) (Procesando AMER)
    (Editor)(Cola) (Procesando EMEA)
    (Editor)(Cola) (Procesando APAC)
    (Cola) (Analiticas globales)
    ((Posibilidad) editores multiprotocolos)

    Arriba se muestra un ejemplo de cómo se puede imaginar el uso de streams. Se tiene un publicador que publica mensajes en un exchange y, según la clave de enrutamiento de los mensajes, se enrutan a diferentes colas. Por lo tanto, se tiene una cola para cada región del mundo. Por ejemplo, se tiene una cola para las Américas, una para Europa, una para Asia y una para la sede. Se tiene una aplicación consumidora dedicada que realizará un procesamiento específico para cada región.

    Si se actualiza a RabbitMQ 3.9 o posterior, se puede simplemente crear un stream, vincularlo al exchange con un comodín para que todos los mensajes se enruten a las colas pero el stream reciba todos los mensajes. Luego se puede dirigir una aplicación que utiliza el Protocolo Stream a este stream y podemos imaginar que esta aplicación realizará análisis mundiales todos los días sin siquiera leer el stream muy rápido. Así es como podemos imaginar que los streams se ajustan a las aplicaciones existentes.

    Garantías para RabbitMQ Streams

    Los streams admiten entrega al menos una vez, ya que admiten un mecanismo similar a AMQP Publish Confirms. También hay un mecanismo de deduplicación, el agente filtra los mensajes duplicados según el número de secuencia de publicación, como una clave en una base de datos o un número de línea en un archivo.

    Text from the image: (Garantías)                              (Mensajes de deduplicación)                (Control de flujo)
    (Al menos uno)                        (publicando)
    (Sin pérdida de mensajes)

    En ambos lados, tenemos control de flujo, por lo que se bloquearán las conexiones TCP de los editores rápidos. El corredor solo enviará mensajes al cliente cuando esté listo para aceptarlos.

    Resumen

    Text from the image: (Streams: una nueva estructura de tipo de registro replicada y persistente en RabbitMQ)
    (Desbloquear los nuevos escenarios con RabbitMQ)
    (Grandes fan-outs) (Repetición/tiempo de viaje)(Alto rendimiento)(Grandes registros)

    (Pruebalo)

    Los Streams son una nueva estructura de datos replicada y persistente en RabbitMQ, que modelan un registro de solo anexión. Son buenos para distribución masiva, soportan funciones de reproducción y viaje en el tiempo, son adecuados para escenarios de alto rendimiento y para grandes registros. Almacenan sus datos en el sistema de archivos y nunca en memoria.

    Si crees que los Streams o RabbitMQ podrían ser útiles para ti pero no sabes por dónde empezar, habla con nuestros expertos , siempre estamos dispuestos a ayudar. Si quieres ver las últimas características y estudios de casos del mundo de RabbitMQ, únete a nosotros en RabbitMQ Summit 2022.

    The post Presentamos el soporte de transmisión en RabbitMQ appeared first on Erlang Solutions .

    • wifi_tethering open_in_new

      This post is public

      www.erlang-solutions.com /blog/presentamos-el-soporte-de-transmision-en-rabbitmq/

    • chevron_right

      Ignite Realtime Blog: Botz version 1.2.0 release

      news.movim.eu / PlanetJabber · Thursday, 9 March, 2023 - 15:46

    We have just released version 1.2.0 of the Botz framework for Openfire!

    The Botz library adds to the already rich and extensible Openfire with the ability to create internal user bots.

    In this release, a bug that prevented client sessions for bots from being created was fixed. Hat-tip to
    Kris Iyer for working with us on a fix!

    Download the latest version of the Botz framework from its project page !

    For other release announcements and news follow us on Twitter and Mastodon .

    1 post - 1 participant

    Read full topic

    • chevron_right

      Erlang Solutions: Creating a simple weather application with Phoenix LiveView

      news.movim.eu / PlanetJabber · Thursday, 9 March, 2023 - 10:00 · 7 minutes

    Introduction

    In this article we will discuss our experience building an online weather application in Elixir using Phoenix LiveView. We created a real-time weather application that allows users to see the past, current, and forecast temperature and precipitation data for any UK postcode. The goals of building this app were:

    • to further familiarise ourselves with Phoenix LiveView
    • to investigate some of the libraries available for displaying graphs in LiveView

    Our reason for displaying both temperature and precipitation data simultaneously was to test the capabilities of the libraries in question, as some rather complex graph configurations are required to display two lines on one y-axis (minimum and maximum temperature) and an additional line on a second, independent y-axis (precipitation).

    We wrote our app’s front-end using a combination of simple HTML attributes and Phoenix LiveView’s built-in hooks to create dynamic behaviour without any JavaScript. For example, when the user inputs a postcode and submits the form, a new graph for the temperature and precipitation in the given area is instantly generated.

    We investigated two libraries in order to generate our graphs: Contex and Vega-Lite. Contex is a simple library for generating charts and plots in Elixir by generating SVG output. Vega-Lite is a more general tool, a high-level language (based on Vega, a declarative language for creating interactive visualisations) with various functionality for different common graph types, where the visualisation is created as a JSON object.

    Using APIs and creating an input form

    Before we could work with any graph libraries, our first task was to use an open-source API to retrieve the weather data we required for the graph. We began by getting the current temperature for a fixed “default” postcode, to ensure it was working correctly. It was not difficult to find an API that suited our purposes. We soon came across Open-Meteo, which contained all the information we needed: the current temperature, the maximum and minimum temperature for a given day, the seven-day forecast, and the precipitation.

    However, this API came with a limitation: it was only able to retrieve the weather for a given latitude and longitude, rather than for a given postcode. Due to this, we had to find a second open-source API, which could fetch the latitude and longitude for a given postcode. We ultimately landed on the API provided by postcodes.io for this purpose. We then followed this up with a call to Open-Meteo, so that when the application was fully set up inserting a postcode would seamlessly fetch the relevant temperature data for that location. The following code shows the function to retrieve this information and add it to the LiveView socket:

    elixir
    def assign_temp_and_location(socket, location) do
      {coordinates, admin_ward} = Weather.get_location(location)
      temperature = Weather.get_weather(coordinates)
    
      assign(socket,
        temperature: temperature,
        admin_ward: admin_ward
      )
    end
    
    

    Having achieved this, our next task was simple: creating an input field to allow the user to specify a postcode that we would then fetch the weather data for. We were able to implement this using a simple HTML form element which, upon submission, queries the APIs and generates a new graph based on the data received.

    Creating a graph with Contex

    At this stage we had a barebones implementation of the current temperature through an input field. The next step of the process was expanding this from a basic plaintext temperature display to a more detailed graph containing the forecast, maximum and minimum temperature, and precipitation. We needed to make use of an external library to accomplish this, and originally found Contex, which allows for the creation and rendering of SVG charts through Elixir. This initially seemed like the right call, as the Contex charts were neat and legible, and the code needed to create them was relatively simple:

    elixir
    defp assign_chart_svg(%{assigns: %{chart: chart, admin_ward: admin_ward}} = socket) do
      assign(socket,
        :chart_svg,
        Contex.Plot.new(700, 400, chart)
        |> Contex.Plot.titles("Daily maximum and minimum temperature in #{admin_ward}", "")
        |> Contex.Plot.axis_labels("Date", "Temperature")
        |> Contex.Plot.plot_options(%{legend_setting: :legend_right})
        |> Contex.Plot.to_svg()
      )
    end
    
    

    However, problems soon arose with attempting to use this library for our purposes. Firstly, Contex would not allow for the setting of custom intervals on a line graph, meaning when trying to include both the seven-day history and seven-day forecast the x-axis would be abbreviated, with an interval every two days instead of every day. Secondly, our desire to make use of multiple y-axes to display both the maximum and minimum temperature and the precipitation simultaneously was not possible.

    The graph generated by Contex

    Exacerbating this problem was Contex’s documentation, which was very limited, particularly for line charts, a relatively recent addition to the library. This meant that it was difficult to ascertain whether there were solutions to our problems. Unable to achieve what we set out for with Contex, we opted to investigate different libraries.

    From Contex to Vega-Lite

    We were recommended to look at Vega-Lite, which has very thorough documentation for the JSON specification. By combining this with the documentation for Vega-Lite Elixir bindings, we had the possibility to generate graphs with much greater functionality than Contex had provided.

    Vega-Lite is very powerful, and using it allowed us to easily display both the seven-day history and the seven-day forecast data received from the API. We were also able to show the precipitation in addition to the temperature data, each with its own independent y-axis. We could also modify the colours of the lines, add axis labels and modify their angles for optimum visual appeal. We were also able to add a vertical line in the middle of the graph, indicating the data points for the current date.

    |The graph generated by Contex

    It’s worth noting however, that when using the Vega-Lite Elixir bindings, all of the options have been normalised to snake-case atom keys. For example, in axis (for colouring the axes labels), the field is title_colour :, rather than ` titleColor :` as given in the JSON specification. This caused us some brief trouble when at first we used the camel-case version, and the options were not displaying. The following is a partial excerpt of the code used for the graph:

    elixir
    new_chart = Vl.new(width: 700, height: 400, resolve: [scale: [y: "independent"]])
    
    chart =
      Vl.data_from_values(new_chart, dataset)
      |> Vl.layers([
        Vl.new()
        |> Vl.layers([
          Vl.new()
          |> Vl.mark(:line, color: "#FF2D00")
          |> Vl.encode_field(:x, "date", type: :ordinal, title: "Date", axis: [label_angle: -45])
          |> Vl.encode_field(:y, "max", type: :quantitative, title: "Maximum temperature"),
    

    In order to render the Vega-Lite graphs to a usable format (in our case SVG) we needed the VegaLite.Export functions. Unfortunately for SVG, PDF, and PNG exports, these functions rely on npm packages, meaning we had to add Node.js, npm, and some additional Vega and Vega-Lite dependencies to our project. Exporting the graph as an SVG was the best option as it allowed us to reuse code from the Contex implementation and display the graph in our HTML page render as we had before, but if we had wanted to avoid installing the npm packages, it would also have been possible to export the graph directly to HTML or as a JSON instead.

    Conclusion

    At the end of the process, we had broadly succeeded in creating what we set out to create: a Phoenix LiveView app that could display the weather and precipitation data for a week on either side of the current date for any given UK postcode, in a neat and colour-coded line graph. We came away from the process with both a better understanding of LiveView and a good idea of the strengths and weaknesses of the two libraries we utilised.

    Contex provides a simpler and lightweight functionality, making it easy to create basic graphs. However, its comparatively limited library and its insufficient documentation provide obstacles to using it for more complex graphs, and as such it ultimately proved unsuitable for our purposes. Meanwhile, Vega-Lite is thoroughly documented and contains more intricate and advanced functionality, allowing us to create the application as outlined. Despite this, it does also have several drawbacks: its language-agnostic documentation occasionally made it slightly confusing to implement in Elixir, and the packages necessary to export the graphs create a significant JavaScript footprint in the application. When working on a project that could require one of these two libraries, it might help to consider these strengths and weaknesses in order to determine which would be the best fit.

    References

    Weather application on Github

    Open-Meteo API

    Postcodes API

    Contex documentation

    Vega-Lite documentation

    Vega-Lite Elixir bindings documentation

    The post Creating a simple weather application with Phoenix LiveView appeared first on Erlang Solutions .

    • wifi_tethering open_in_new

      This post is public

      www.erlang-solutions.com /blog/creating-a-simple-weather-application-with-phoenix-liveview/