introduce request guards in jira agent

Konstantin Nazarov 10 years ago
parent
commit
affa0e472a
1 changed files with 20 additions and 2 deletions
  1. 20 2
      app/models/agents/jira_agent.rb

+ 20 - 2
app/models/agents/jira_agent.rb

@@ -14,6 +14,7 @@ module Agents
14 14
       `jira_url` specifies the full URL of the jira installation, including https://
15 15
       `jql` is an optional Jira Query Language-based filter to limit the flow of events. See [JQL Docs](https://confluence.atlassian.com/display/JIRA/Advanced+Searching) for details. 
16 16
       `username` and `password` are optional, and may need to be specified if your Jira instance is read-protected
17
+      `timeout` is an optional parameter that specifies how long the request processing may take in minutes.
17 18
 
18 19
       The agent does periodic queries and emits the events containing the updated issues in JSON format.
19 20
       NOTE: upon the first execution, the agent will fetch everything available by the JQL query. So if it's not desirable, limit the `jql` query by date.
@@ -34,6 +35,7 @@ module Agents
34 35
     MD
35 36
 
36 37
     default_schedule "every_10m"
38
+    MAX_REQUESTS = 10
37 39
 
38 40
     def default_options
39 41
       {
@@ -41,13 +43,15 @@ module Agents
41 43
         'password' => '',
42 44
         'jira_url' => 'https://jira.atlassian.com',
43 45
         'jql' => '',
44
-        'expected_update_period_in_days' => '7'
46
+        'expected_update_period_in_days' => '7',
47
+        'timeout' => '1'
45 48
       }
46 49
     end
47 50
 
48 51
     def validate_options
49 52
       errors.add(:base, "you need to specify your jira URL") unless options['jira_url'].present?
50 53
       errors.add(:base, "you need to specify the expected update period") unless options['expected_update_period_in_days'].present?
54
+      errors.add(:base, "you need to specify request timeout") unless options['timeout'].present?
51 55
     end
52 56
 
53 57
     def working?
@@ -107,10 +111,12 @@ module Agents
107 111
         jql = "(#{options[:jql]}) and updated >= '#{since.strftime('%Y-%m-%d %H:%M')}'"
108 112
       else
109 113
         jql = options[:jql] if !options[:jql].empty?
110
-        jql = "updated >= '#{since.strftime('%Y-%m-%d %H:%M')} GMT'" if since
114
+        jql = "updated >= '#{since.strftime('%Y-%m-%d %H:%M')}'" if since
111 115
       end
112 116
 
117
+      start_time = Time.now
113 118
 
119
+      request_limit = 0
114 120
       loop do
115 121
         response = HTTParty.get(request_url(jql, startAt), request_options)
116 122
 
@@ -122,6 +128,18 @@ module Agents
122 128
           raise RuntimeError.new("Request failed: #{response}")
123 129
         end
124 130
 
131
+        if response['issues'].length == 0
132
+          request_limit+=1
133
+        end
134
+
135
+        if request_limit > MAX_REQUESTS
136
+          raise RuntimeError("There is no progress while fetching issues")
137
+        end
138
+
139
+        if Time.now > start_time + options['timeout'].to_i * 60
140
+          raise RuntimeError("Timeout exceeded while fetching issues")
141
+        end
142
+
125 143
         issues += response['issues']
126 144
         startAt += response['issues'].length
127 145