techempower.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. const stringify = require('@stringify')
  2. const html = require('@html')
  3. const cache = require('@cache')
  4. const dns = require('@dns')
  5. const postgres = require('@pg')
  6. const http = require('@http')
  7. const socket = require('@socket')
  8. const util = require('util.js')
  9. const config = require('tfb.config.js')
  10. const { getIPAddress } = dns
  11. const { createSocket } = socket
  12. const { createServer, responses } = http
  13. const { SimpleCache } = cache
  14. const { sprayer, sortByMessage, spawn, getUpdateQuery, Clock } = util
  15. const { sjs, attr } = stringify
  16. const {
  17. db, fortunes, worlds, templates,
  18. maxQuery, maxRows, message, json,
  19. extra
  20. } = config
  21. async function main () {
  22. const spray = sprayer(maxQuery)
  23. const getRandom = () => Math.ceil(Math.random() * maxRows)
  24. const getCount = (qs = { q: 1 }) => {
  25. return Math.min(parseInt((qs.q) || 1, 10), maxQuery) || 1
  26. }
  27. const sJSON = sjs({ message: attr('string') })
  28. const wJSON = sjs({ id: attr('number'), randomnumber: attr('number') })
  29. const clock = new Clock()
  30. const sock = createSocket()
  31. const ip = await getIPAddress(db.hostname)
  32. await sock.connect(ip, db.port)
  33. const pg = await postgres.createSocket(sock, db)
  34. sock.noDelay = false
  35. const getWorldById = await pg.compile(worlds)
  36. const getFortunes = await pg.compile(fortunes)
  37. const worldCache = new SimpleCache(id => getWorldById(id))
  38. const template = html.load(templates.fortunes, templates.settings)
  39. const getRandomWorld = () => getWorldById(getRandom())
  40. const getCachedWorld = () => worldCache.get(getRandom())
  41. const server = createServer()
  42. .get('/plaintext', res => res.text(message))
  43. .get('/json', res => res.utf8(sJSON(json), responses.json))
  44. .get('/db', async res => {
  45. res.utf8(wJSON(await getRandomWorld()), responses.json)
  46. })
  47. .get('/fortunes', async res => {
  48. res.html(template.call(sortByMessage([extra, ...await getFortunes()])))
  49. })
  50. .get('/cached-world', async (res, req) => {
  51. res.json(await Promise.all(spray(getCount(req.query), getCachedWorld)))
  52. })
  53. .get('/query', async (res, req) => {
  54. res.json(await Promise.all(spray(getCount(req.query), getRandomWorld)))
  55. })
  56. .get('/update', async (res, req) => {
  57. const count = getCount(req.query)
  58. const worlds = await Promise.all(spray(count, getRandomWorld))
  59. const updateWorlds = await getUpdateQuery(count, pg)
  60. await updateWorlds(...worlds.map(w => {
  61. w.randomnumber = getRandom()
  62. return [w.id, w.randomnumber]
  63. }).flat())
  64. res.json(worlds)
  65. })
  66. .listen('0.0.0.0', 8080)
  67. clock.set(() => {
  68. worldCache.tick()
  69. server.update()
  70. })
  71. }
  72. spawn(main).catch(err => just.error(err.stack))