|
34 | 34 | MAX_RETRIES = 3
|
35 | 35 |
|
36 | 36 |
|
| 37 | +def chunks(lst, n): |
| 38 | + """Yield successive n-sized chunks from lst.""" |
| 39 | + for i in range(0, len(lst), n): |
| 40 | + yield lst[i:i + n] |
| 41 | + |
| 42 | + |
37 | 43 | class ServiceXAdapter:
|
38 | 44 | def __init__(self, endpoint, file_prefix=None):
|
39 | 45 | self.endpoint = endpoint
|
@@ -88,6 +94,32 @@ def put_file_add(self, file_info):
|
88 | 94 | self.logger.error(f'After {attempts} tries, failed to send ServiceX App a put_file '
|
89 | 95 | f'message: {str(file_info)} - Ignoring error.')
|
90 | 96 |
|
| 97 | + def put_file_add_bulk(self, file_list): |
| 98 | + for chunk in chunks(file_list, 20): |
| 99 | + success = False |
| 100 | + attempts = 0 |
| 101 | + mesg = [] |
| 102 | + for fi in chunk: |
| 103 | + mesg.append({ |
| 104 | + "timestamp": datetime.now().isoformat(), |
| 105 | + "paths": [self._prefix_file(fp) for fp in fi['paths']], |
| 106 | + 'adler32': fi['adler32'], |
| 107 | + 'file_size': fi['file_size'], |
| 108 | + 'file_events': fi['file_events'] |
| 109 | + }) |
| 110 | + while not success and attempts < MAX_RETRIES: |
| 111 | + try: |
| 112 | + requests.put(self.endpoint + "/files", json=mesg) |
| 113 | + self.logger.info(f"Metric: {json.dumps(mesg)}") |
| 114 | + success = True |
| 115 | + except requests.exceptions.ConnectionError: |
| 116 | + self.logger.exception(f'Connection error to ServiceX App. Will retry ' |
| 117 | + f'(try {attempts} out of {MAX_RETRIES}') |
| 118 | + attempts += 1 |
| 119 | + if not success: |
| 120 | + self.logger.error(f'After {attempts} tries, failed to send ServiceX App a put_file_bulk ' |
| 121 | + f'message: {mesg} - Ignoring error.') |
| 122 | + |
91 | 123 | def post_transform_start(self):
|
92 | 124 | success = False
|
93 | 125 | attempts = 0
|
|
0 commit comments