queries.js 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. var pendingQueries = []
  2. var runningQueries = []
  3. var maxQueries = 3
  4. function runQuery(data, success, error) {
  5. data.run_id = uuid()
  6. var query = {
  7. data: data,
  8. success: success,
  9. error: error,
  10. run_id: data.run_id,
  11. data_source: data.data_source,
  12. canceled: false
  13. }
  14. pendingQueries.push(query)
  15. runNext()
  16. return query
  17. }
  18. function runNext() {
  19. if (runningQueries.length < maxQueries) {
  20. var query = pendingQueries.shift()
  21. if (query) {
  22. runningQueries.push(query)
  23. runQueryHelper(query)
  24. runNext()
  25. }
  26. }
  27. }
  28. function runQueryHelper(query) {
  29. var xhr = $.ajax({
  30. url: Routes.run_queries_path(),
  31. method: "POST",
  32. data: query.data,
  33. dataType: "html"
  34. }).done( function (d) {
  35. if (d[0] == "{") {
  36. var response = $.parseJSON(d)
  37. query.data.blazer = response
  38. setTimeout( function () {
  39. if (!query.canceled) {
  40. runQueryHelper(query)
  41. }
  42. }, 1000)
  43. } else {
  44. if (!query.canceled) {
  45. query.success(d)
  46. }
  47. queryComplete(query)
  48. }
  49. }).fail( function(jqXHR, textStatus, errorThrown) {
  50. if (!query.canceled) {
  51. var message = (typeof errorThrown === "string") ? errorThrown : errorThrown.message
  52. if (!message) {
  53. message = "An error occurred"
  54. }
  55. query.error(message)
  56. }
  57. queryComplete(query)
  58. })
  59. query.xhr = xhr
  60. return xhr
  61. }
  62. function queryComplete(query) {
  63. var index = runningQueries.indexOf(query)
  64. runningQueries.splice(index, 1)
  65. runNext()
  66. }
  67. function uuid() {
  68. return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
  69. var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8)
  70. return v.toString(16)
  71. })
  72. }
  73. function cancelAllQueries() {
  74. pendingQueries = []
  75. for (var i = 0; i < runningQueries.length; i++) {
  76. cancelQuery(runningQueries[i])
  77. }
  78. }
  79. $(window).unload(cancelAllQueries)
  80. function cancelQuery(query) {
  81. query.canceled = true
  82. if (query.xhr) {
  83. query.xhr.abort()
  84. }
  85. // tell server
  86. var path = Routes.cancel_queries_path()
  87. var data = {run_id: query.run_id, data_source: query.data_source}
  88. if (navigator.sendBeacon) {
  89. navigator.sendBeacon(path + "?" + $.param(csrfProtect(data)))
  90. } else {
  91. // TODO make sync
  92. $.post(path, data)
  93. }
  94. }
  95. function csrfProtect(payload) {
  96. var param = $("meta[name=csrf-param]").attr("content")
  97. var token = $("meta[name=csrf-token]").attr("content")
  98. if (param && token) payload[param] = token
  99. return payload
  100. }