Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DO NOT MERGE] Very dirty version of lumberjack and HTTP echo server support. #504

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

mashhurs
Copy link
Contributor

@mashhurs mashhurs commented Sep 23, 2024

Description

Super simple stupid PoC of supporting Lumberjack and HTTP echo server.

How to test

  • Test with lumberjack client
# encoding: utf-8

Thread.abort_on_exception = true
require "socket"
require "thread"
require "zlib"
require "json"
require 'logger'

Thread.abort_on_exception = true
HOST="127.0.0.1"
PORT=3333

LOGGER = Logger.new(STDOUT)

module Lumberjack
  SEQUENCE_MAX = (2**32-1).freeze

  class Client
    def initialize
      @sequence = 0
      @last_ack = 0
      @socket = connect
    end

    private
    def connect
      socket = TCPSocket.new(HOST, PORT)
    end

    public
    def handshake(client_n)
      LOGGER.info "client #{client_n}: Lumberjack protocol handshaking..."
      handshake_msg = "notl"
      send_payload(handshake_msg)
    end

    def write(elements)
      elements = [elements] if elements.is_a?(Hash)
      send_window_size(elements.size)

      payload = elements.map { |element| JsonEncoder.to_frame(element, inc) }.join
      compressed_payload = compress_payload(payload)
      send_payload(compressed_payload)
    end

    private
    def inc
      @sequence = 0 if @sequence + 1 > Lumberjack::SEQUENCE_MAX
      @sequence = @sequence + 1
    end

    private
    def send_window_size(size)
      @socket.syswrite(["2", "W", size].pack("AAN"))
    end

    private 
    def compress_payload(payload)
      compress = Zlib::Deflate.deflate(payload)
      ["1", "C", compress.bytesize, compress].pack("AANA*")
    end

    private
    def send_payload(payload)
      written = 0
      while written < payload.size
        written += @socket.syswrite(payload[written..-1])
      end
    end

    public
    def ack
      _, type = read_version_and_type
      raise "Whoa we shouldn't get this frame: #{type}" if type != "A"
      @last_ack = read_last_ack
    end

    private
    def read_version_and_type
      version = @socket.read(1)
      type    = @socket.read(1)
      [version, type]
    end

    private
    def read_last_ack
      @socket.read(4).unpack("N").first
    end

    public
    def close
      @socket.close
    end
  end

  module JsonEncoder
    def self.to_frame(hash, sequence)
      json = hash.to_json
      json_length = json.bytesize
      pack = "AANNA#{json_length}"
      frame = ["2", "J", sequence, json_length, json]
      frame.pack(pack)
    end
  end

end

def send_message(client, client_n)
  LOGGER.info "client #{client_n}: writing message"
  data = { "message" => "Knock knock (make me ack) with Lumberjack." }
  client.write([data])
  LOGGER.info "client #{client_n}: wrote"
  loop do
    written = client.ack
    break if written != 0
  end
  LOGGER.info "client #{client_n}: got ack"
end

n_clients = 1
clients = n_clients.times.map do |n|
  Thread.new do
    client = Lumberjack::Client.new
    current_client_no = n+1
    client.handshake(current_client_no)
    send_message(client, current_client_no)
    send_message(client, current_client_no)
  end
end
clients.each(&:join)
  • Test with HTTP client
# encoding: utf-8

require 'uri'
require 'net/http'

server_url = 'http://localhost:3333?oTel'
uri = URI(server_url)

puts "Calling #{server_url}"

res = Net::HTTP.get_response(uri)

puts "Response: #{res.inspect}"
puts res.body if res.is_a?(Net::HTTPSuccess)

@mashhurs mashhurs marked this pull request as draft September 23, 2024 23:46
@mashhurs mashhurs changed the title Very dirty version of lumberjack and HTTP echo server. [DO NOT MERGE] Very dirty version of lumberjack and HTTP echo server. Sep 24, 2024
@mashhurs mashhurs changed the title [DO NOT MERGE] Very dirty version of lumberjack and HTTP echo server. [DO NOT MERGE] Very dirty version of lumberjack and HTTP echo server support. Sep 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants