Register
Login
Resources
Docs Blog Datasets Glossary Case Studies Tutorials & Webinars
Product
Data Engine LLMs Platform Enterprise
Pricing Explore
Connect to our Discord channel

hydro.js 2.6 KB

You have to be logged in to leave a comment. Sign In
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
  1. const crypto = require('crypto')
  2. const fetch = require('node-fetch')
  3. const statsd = require('../lib/statsd')
  4. const FailBot = require('../lib/failbot')
  5. const SCHEMAS = {
  6. page: 'docs.v0.PageEvent',
  7. exit: 'docs.v0.ExitEvent',
  8. link: 'docs.v0.LinkEvent',
  9. search: 'docs.v0.SearchEvent',
  10. navigate: 'docs.v0.NavigateEvent',
  11. survey: 'docs.v0.SurveyEvent',
  12. experiment: 'docs.v0.ExperimentEvent',
  13. redirect: 'docs.v0.RedirectEvent',
  14. clipboard: 'docs.v0.ClipboardEvent',
  15. print: 'docs.v0.PrintEvent'
  16. }
  17. module.exports = class Hydro {
  18. constructor ({ secret, endpoint } = {}) {
  19. this.secret = secret || process.env.HYDRO_SECRET
  20. this.endpoint = endpoint || process.env.HYDRO_ENDPOINT
  21. this.schemas = SCHEMAS
  22. }
  23. /**
  24. * Can check if it can actually send to Hydro
  25. */
  26. maySend () {
  27. return Boolean(this.secret && this.endpoint)
  28. }
  29. /**
  30. * Generate a SHA256 hash of the payload using the secret
  31. * to authenticate with Hydro
  32. * @param {string} body
  33. */
  34. generatePayloadHmac (body) {
  35. return crypto.createHmac('sha256', this.secret)
  36. .update(body)
  37. .digest('hex')
  38. }
  39. /**
  40. * Publish a single event to Hydro
  41. * @param {string} schema
  42. * @param {any} value
  43. */
  44. async publish (schema, value) {
  45. return this.publishMany([{ schema, value }])
  46. }
  47. /**
  48. * Publish multiple events to Hydro
  49. * @param {[{ schema: string, value: any }]} events
  50. */
  51. async publishMany (events) {
  52. const body = JSON.stringify({
  53. events: events.map(({ schema, value }) => ({
  54. schema,
  55. value: JSON.stringify(value), // We must double-encode the value property
  56. cluster: 'potomac' // We only have ability to publish externally to potomac cluster
  57. }))
  58. })
  59. const token = this.generatePayloadHmac(body)
  60. const doFetch = () => fetch(this.endpoint, {
  61. method: 'POST',
  62. body,
  63. headers: {
  64. Authorization: `Hydro ${token}`,
  65. 'Content-Type': 'application/json',
  66. 'X-Hydro-App': 'docs-production'
  67. }
  68. })
  69. const res = await statsd.asyncTimer(doFetch, 'hydro.response_time')()
  70. const statTags = [`response_code:${res.status}`]
  71. statsd.increment(`hydro.response_code.${res.status}`, 1, statTags)
  72. statsd.increment('hydro.response_code.all', 1, statTags)
  73. // Track hydro exceptions in Sentry, but don't track 503s because we can't do anything about service availability
  74. if (!res.ok && res.status !== 503) {
  75. const err = new Error(`Hydro request failed: ${res.statusText}`)
  76. err.status = res.status
  77. FailBot.report(err, {
  78. hydroStatus: res.status,
  79. hydroText: res.statusText
  80. })
  81. throw err
  82. }
  83. return res
  84. }
  85. }
Tip!

Press p or to see the previous file or, n or to see the next file

Comments

Loading...