Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • 19:37
    asterite synchronize #12165
  • 19:34
    asterite synchronize #12165
  • 17:55
    beta-ziliani milestoned #12149
  • 12:32
    Blacksmoke16 unlabeled #12165
  • 12:32
    Blacksmoke16 labeled #12165
  • 12:32
    Blacksmoke16 labeled #12165
  • 12:32
    Blacksmoke16 labeled #12165
  • 11:56
    asterite opened #12165
  • Jun 26 21:23
    straight-shoota milestoned #12163
  • Jun 26 21:23
    straight-shoota edited #12163
  • Jun 26 21:18
    straight-shoota milestoned #11773
  • Jun 26 21:18
    straight-shoota milestoned #12008
  • Jun 26 21:15
    straight-shoota unlabeled #5659
  • Jun 26 21:12
    straight-shoota milestoned #11872
  • Jun 26 21:12
    straight-shoota milestoned #11909
  • Jun 26 21:12
    straight-shoota milestoned #11991
  • Jun 26 21:11
    straight-shoota milestoned #12026
  • Jun 26 18:17
    Blacksmoke16 labeled #12164
  • Jun 26 18:15
    zw963 labeled #12164
  • Jun 26 18:15
    zw963 opened #12164
From IRC (bridge bot)
@FromIRC
<xyhuvud> todays exercise was so easy and short the top list server crashed due to load :X
Ary Borenszweig
@asterite
Really? That's great news. I guess I'll be streaming for just a few minutes then. I think Eric puts an easy exercise after a tough one (yesterday wasn't that hard, but you needed to think about a different way to represent things)
ddd
@Dan-Do
How can I tell crystal build to use a single "header only" (.h without .c)?
ddd
@Dan-Do
I made a fake.c
# include "header.h"
But after compiled with gcc -c ... the object file removed two functions. Weird!
From IRC (bridge bot)
@FromIRC
<riza> @asterite oh, great suggestion, thank you
From IRC (bridge bot)
@FromIRC
<holst> I have a couple of observations: Crystal lang needs something that is taggable and searchable; crystal lang is not. crlang vs. #crlang is great ;⁠-)
<holst> Also, I think the Goals of the project are non-orthogonal. In total 6 goals but they can be reduced down to at least 5 or even 4 if we accept the fact that OOP is not a goal in itself
<holst> Have anyone written a good JSON / microservice tutorial for crlang? I think I am struggling a lot with moving from say Python or Javascript to Crlang due to the parsing and typing requirements. I have been looking for some kind of best practice guide for this but I have not found one
<holst> do we really need to define the complete API response univerise in the client application just to "get some job done"? If so it puts a great barrier to writing small client apps that uses a big server API
<holst> case in mind: docker engine API
From IRC (bridge bot)
@FromIRC
<holst> and kubernetes API
<straight-shoota> What do you mean with "complete API response univerise"?
<holst> the generated APIs are completely terrible, 100K LOC monsters
<straight-shoota> What generated APIs? Who generated them and why?
<holst> say you do docker inspect <container> there might be a lot of data in there which is mostly useles to the application that did the query.
<holst> @straight-shoota: the generated APIs are by the project maintainers (obviously not generated for crystal)
<straight-shoota> I don't follow what your asking about
<straight-shoota> I believe you have assumed some implicit context, but it does not communicate
<holst> thats the complete output for a docker inspect
<straight-shoota> yes, I got that. Still don't know what your problem is
<holst> If I were to implement a complete class description for the entire response I would just not use crlang for that
<straight-shoota> y not?
From IRC (bridge bot)
@FromIRC
<holst> Useless work. I do not have any need for the code that talks about the Network parameters say. So why would I write code for it
George Dietrich
@Blacksmoke16
could also just use JSON.parse ofc. then you have to deal with typing in a more painful to use way like data.as_a[0].as_h["Id"].as_s versus data[0].id
From IRC (bridge bot)
@FromIRC
<holst> I would prefer if I could work with a dynamic type instead to at least dig myself down to the part that I am interested in
George Dietrich
@Blacksmoke16
fwiw you dont need to add properties and stuff for things you wont need
From IRC (bridge bot)
@FromIRC
<straight-shoota> I don't know. But you stated as a premise that you wanted a complete class representation of that JSON data
<holst> I think that is the opposite of what I wanted
<holst> I questioned if that was the way to go in a typed language like crlang; or golang which has a generated API; that is typically what they do
<straight-shoota> You can go completely dynamic with JSON.parse as Blacksmoke16 mentioned. Or you use JSON::Serializable and only add mappings for the fields your interested about.
<holst> So you can have a "view" of a type and have the non-referenced fields just dropped?
<straight-shoota> Yes
<holst> Ok, I will try something out and ask for some feedback if you think its "best practice" style or not
George Dietrich
@Blacksmoke16
From IRC (bridge bot)
@FromIRC
<straight-shoota> This example is a bit more concise: https://play.crystal-lang.org/#/r/cetw
<holst> be brutal ;⁠-) I think the "allOk" logic can be fixed (and it should be "all_ok" I got confused on the coding style recommendation)
From IRC (bridge bot)
@FromIRC
<straight-shoota> You need to set headers before writing the response body. As soon as you print something on the response, the headers get sent.
<straight-shoota> Any later response.status_code = ... or response.content_type = ... don't have any effect
<straight-shoota> for allOk you can use states.all? {|_, state| state.running? }
George Dietrich
@Blacksmoke16
states.each_value.all? &.running?
From IRC (bridge bot)
@FromIRC
<straight-shoota> That's neither shorter nor more performant
George Dietrich
@Blacksmoke16
:shrug: reads better
From IRC (bridge bot)
@FromIRC
<holst> Good stuff, now HttPie reads te output and pretty-prints it too :⁠)
jwaldrip
@jwaldrip:matrix.org
[m]
I am trying to create a web socket proxy, what am i possible doing wrong here? I get an upgrade back from the handler, but then the connection closes and nothing is passed.
require "http"

class Wakr::Handlers::ProxyWebSocket
  include HTTP::Handler

  def initialize(@backend_host : String, @backend_port : Int32)
  end

  def call(context) : Nil
    request = context.request
    response = context.response

    return call_next context unless websocket_upgrade_request? request

    version = request.headers["Sec-WebSocket-Version"]?
    unless version && version == HTTP::WebSocket::Protocol::VERSION
      response.status = :upgrade_required
      response.headers["Sec-WebSocket-Version"] = HTTP::WebSocket::Protocol::VERSION
      Log.error { "Invalid websocket version: `wss://#{request.headers["Host"]?}`#{request.path}" }
      return
    end

    key = request.headers["Sec-WebSocket-Key"]?

    unless key
      response.respond_with_status(:bad_request)
      Log.error { "Invalid request, missing key: `wss://#{request.headers["Host"]?}`#{request.path}" }
      return
    end

    Log.info { "Proxying websocket session: `wss://#{request.headers["Host"]?}`#{request.path}" }
    accept_code = HTTP::WebSocket::Protocol.key_challenge(key)
    response.status = :switching_protocols
    response.headers["Upgrade"] = "websocket"
    response.headers["Connection"] = "Upgrade"
    response.headers["Sec-WebSocket-Accept"] = accept_code
    response.upgrade do |io|
      clients = [
        get_backend_client(request),
        HTTP::WebSocket.new(io, sync_close: false),
      ]
      clients.permutations(2).map do |(source, dest)|
        Log.info { "bonding #{source} and #{dest} "}

        channel = Channel(Bool).new(1)

        # Proxy Ping
        source.on_ping do |message|
          Log.info { "PING" }
          dest.ping(message)
        end

        # Proxy Pong
        source.on_pong do |message|
          Log.info { "PONG" }
          dest.pong(message)
        end

        # Proxy Message
        source.on_message do |message|
          Log.info { "MESSAGE" }
          dest.send(message)
        end

        # Proxy Close
        source.on_close do |code, message|
          Log.info { "CLOSE" }
          dest.close(code, message)
          channel.send true
        end

        # Proxy Binary
        source.on_binary do |bytes|
          Log.info { "BINARY" }
          dest.stream do |stream_io|
            stream_io.write bytes
          end
        end

        # Run the source socket
        spawn {
          Log.info { "running #{source}" }
          source.run
        }

        # Return a waiting function
        ->{
          Fiber.yield
          Log.info { "waiting for close: #{source}" }
          channel.receive
          Log.info { "closed: #{source}" }
        }
      end.each(&.call)
    end
  end

  private def websocket_upgrade_request?(request)
    return false unless upgrade = request.headers["Upgrade"]?
    return false unless upgrade.compare("websocket", case_insensitive: true) == 0

    request.headers.includes_word?("Connection", "Upgrade")
  end

  private def get_backend_client(request)
    HTTP::WebSocket.new(
      host: @backend_host,
      path: request.resource,
      port: @backend_port,
      headers: request.headers
    )
  end
end
From IRC (bridge bot)
@FromIRC
<holst> Thanks guys. If anyone of you are using Docker Engine for some workloads, this might be interesting for you to use as uptime probe: https://github.com/morecontainers/docker-state
George Dietrich
@Blacksmoke16
https://github.com/morecontainers/docker-state/blob/master/Dockerfile#L4 It's prob not actually going to be static given its being compiled in ubuntu
also prob want --release flag