queries.js 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  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. query.error(message)
  53. }
  54. queryComplete(query)
  55. })
  56. query.xhr = xhr
  57. return xhr
  58. }
  59. function queryComplete(query) {
  60. var index = runningQueries.indexOf(query)
  61. runningQueries.splice(index, 1)
  62. runNext()
  63. }
  64. function uuid() {
  65. return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
  66. var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8)
  67. return v.toString(16)
  68. })
  69. }
  70. function cancelAllQueries() {
  71. pendingQueries = []
  72. for (var i = 0; i < runningQueries.length; i++) {
  73. cancelQuery(runningQueries[i])
  74. }
  75. }
  76. $(window).unload(cancelAllQueries)
  77. function cancelQuery(query) {
  78. query.canceled = true
  79. if (query.xhr) {
  80. query.xhr.abort()
  81. }
  82. // tell server
  83. var path = Routes.cancel_queries_path()
  84. var data = {run_id: query.run_id, data_source: query.data_source}
  85. if (navigator.sendBeacon) {
  86. navigator.sendBeacon(path, csrfProtect(data))
  87. } else {
  88. // TODO make sync
  89. $.post(path, data)
  90. }
  91. }
  92. function csrfProtect(payload) {
  93. var param = $("meta[name=csrf-param]").attr("content")
  94. var token = $("meta[name=csrf-token]").attr("content")
  95. if (param && token) payload[param] = token
  96. return new Blob([JSON.stringify(payload)], {type : "application/json; charset=utf-8"})
  97. }