Something like Datalog in Ruby. Aries a placeholder name, can't think of something clever right now.
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

114 řádky
2.3KB

  1. # frozen_string_literal: true
  2. require_relative "aries/version"
  3. require_relative "aries/database"
  4. require "json"
  5. require "socket"
  6. # require "profile"
  7. module Aries
  8. class Error < StandardError; end
  9. # Your code goes here...
  10. def self.action callable
  11. begin
  12. [callable.call, nil]
  13. rescue => e
  14. pp e.backtrace << e
  15. [nil, e]
  16. end
  17. end
  18. def self.valid? commands
  19. for command in commands
  20. command.keys.each do |k|
  21. if ! ["add", "find", "first", "last"].include? k
  22. return [nil, "Undefined command key '#{k}'"]
  23. end
  24. end
  25. end
  26. return [true, nil]
  27. end
  28. host = "localhost"
  29. port = 1234
  30. server = TCPServer.new host, port
  31. puts "Server started, listening #{host}:#{port}"
  32. dbs = {}
  33. db_factory = lambda do |n|
  34. if ! dbs.keys.include? n
  35. dbs[n] = Database.new n
  36. puts "Initialized database #{n}"
  37. end
  38. dbs[n]
  39. end
  40. # ticker thread
  41. Thread.new do
  42. limit = 60 * 10
  43. loop do
  44. dbs.keys.each do |n|
  45. db = dbs[n]
  46. if db.used_at and ((db.used_at.to_i + limit) < Time.now.to_i)
  47. puts "Closing database #{n} it was last used more than #{limit} seconds ago"
  48. dbs.delete n
  49. puts "Closed database #{n}"
  50. end
  51. end
  52. sleep 1
  53. end
  54. end
  55. loop do
  56. Thread.start server.accept do |client|
  57. # client = server.accept
  58. connection = JSON.parse(client.gets)
  59. db = db_factory.call connection['database']
  60. # client.puts "Connected to Aries"
  61. puts "Client connected #{client}"
  62. while commands = client.gets
  63. commands, err = action -> { JSON.parse commands }
  64. if ! err.nil?
  65. client.puts JSON.generate(err: err)
  66. next
  67. end
  68. _, err = valid? commands
  69. if ! err.nil?
  70. client.puts JSON.generate(err: err)
  71. next
  72. end
  73. results = {}
  74. commands.each_with_index do |command, idx|
  75. func, vals = command.to_a.first
  76. begin
  77. results[idx] = db.send(func, vals)
  78. db.used_at = Time.now.to_i
  79. rescue => e
  80. pp [e.backtrace << e]
  81. results = {err: e}
  82. break
  83. end
  84. end
  85. client.puts JSON.generate(results)
  86. end
  87. client.close
  88. puts "Client disconnected #{client}"
  89. end
  90. end
  91. end