def tasks_blocking_by_node_id(node_id): api = api_from_models() # README(shep): Using last_checkin attr for agent-health timestamp = int(time.time()) args = {'node_id': node_id, 'key': 'last_checkin', 'value': timestamp} r = api.attr_create(args) #DB does not hit updater, so we need to notify generic._update_transaction_id('nodes', id_list=[node_id]) generic._update_transaction_id('attrs', id_list=[r['id']]) task = api.task_get_first_by_query("node_id=%d and state='pending'" % int(node_id)) # README(shep): moving this out of a while loop, to let agent-health work semaphore = 'task-for-%s' % node_id flask.current_app.logger.debug('waiting on %s' % semaphore) utility.wait(semaphore) task = api.task_get_first_by_query("node_id=%d and state='pending'" % int(node_id)) if task: utility.clear(semaphore) result = flask.jsonify({'task': task}) else: result = generic.http_notfound(msg='no task found') return result
def object_by_id(object_type, object_id): s_obj = singularize(object_type) api = api_from_models() if flask.request.method == 'PUT': # we just updated something, poke any waiters model_object = api._model_update_by_id(object_type, object_id, flask.request.json) _notify(model_object, object_type, object_id) return http_response(200, '%s Updated' % s_obj.capitalize(), **{s_obj: model_object}) elif flask.request.method == 'DELETE': try: if api._model_delete_by_id(object_type, object_id): return http_response(200, '%s deleted' % s_obj.capitalize()) _notify(None, object_type, object_id) except exceptions.IdNotFound: return http_notfound(msg='not found') elif flask.request.method == 'GET': if 'poll' in flask.request.args: # we're polling semaphore = '%s-id-%s' % (object_type, object_id) utility.wait(semaphore) try: model_object = api._model_get_by_id(object_type, object_id) except exceptions.IdNotFound: return http_notfound(msg='not found') return http_response(200, 'success', **{s_obj: model_object}) else: return http_notfound(msg='Unknown method %s' % flask.request.method)
def f(session_key, txid): """ Accepts a transaction id, and returns a list of updated nodes from input transaction_id to latest transaction_id. transaction dict. FIXME: As an optimization, the changes could be accumulated in a single set up until the point that someone got a new txid. Then we could avoid having a long list of one-element transactions, and instead only create db version intervals on the intervals that we know people could possibly refer from. If that makes sense. Arguments: txid -- transaction id (opaque) Returns: session_key -- unique session key nodes -- list of updated node_ids from trx_id to latest transaction id """ trans = self.transactions[what] current_txid = time.time() if session_key != self.transactions['session_key']: return generic.http_response(410, 'Invalid session_key') txid = float(txid) if 'poll' in request.args: # we'll poll if we have no changes if txid >= max(trans.keys()): semaphore = '%s-changes' % (what) utility.wait(semaphore) if txid < min(trans.keys()): return generic.http_response(410, 'Expired transaction id') retval = set([]) for x in [trans[tx] for tx in trans.keys() if tx > txid]: retval = retval.union(x) return generic.http_response( 200, 'Updated %s' % what.title(), **{"transaction": {'session_key': session_key, 'txid': '%.6f' % current_txid}, what: list(retval)})
def tasks_blocking_by_node_id(node_id): api = api_from_models() # README(shep): Using last_checkin attr for agent-health timestamp = int(time.time()) args = {'node_id': node_id, 'key': 'last_checkin', 'value': timestamp} try: r = api.attr_create(args) except exceptions.IdNotFound: message = 'Node %s not found.' % args['node_id'] return generic.http_notfound(msg=message) except exceptions.IdInvalid: return generic.http_badrequest() #DB does not hit updater, so we need to notify generic._update_transaction_id('nodes', id_list=[node_id]) generic._update_transaction_id('attrs', id_list=[r['id']]) while True: task = api.task_get_first_by_query("node_id=%d and state='pending'" % int(node_id)) if task is None: semaphore = 'task-for-%s' % node_id flask.current_app.logger.debug('waiting on %s' % semaphore) if not utility.wait(semaphore): flask.current_app.logger.error("ERROR ON WAIT") # utility.clear(semaphore) return generic.http_notfound(msg='no task found') else: flask.current_app.logger.error("SUCCESS ON WAIT") else: # utility.clear(semaphore) return generic.http_response(task=task)
def f(session_key, txid): """ Accepts a transaction id, and returns a list of updated nodes from input transaction_id to latest transaction_id. transaction dict. FIXME: As an optimization, the changes could be accumulated in a single set up until the point that someone got a new txid. Then we could avoid having a long list of one-element transactions, and instead only create db version intervals on the intervals that we know people could possibly refer from. If that makes sense. Arguments: txid -- transaction id (opaque) Returns: session_key -- unique session key nodes -- list of updated node_ids from trx_id to latest transaction id """ trans = self.transactions[what] current_txid = time.time() if session_key != self.transactions['session_key']: return generic.http_response(410, 'Invalid session_key') txid = float(txid) if 'poll' in request.args: # we'll poll if we have no changes if txid >= max(trans.keys()): semaphore = '%s-changes' % (what) utility.wait(semaphore) if txid < min(trans.keys()): return generic.http_response(410, 'Expired transaction id') retval = set() for x in (trans[tx] for tx in trans.keys() if tx > txid): retval.update(x) #tenant start #target_tenant = 'test2-tenant' #Temporary #log("start") target_tenant = request.headers.get('tenant') if what == 'nodes' and not generic.is_adminTenant(target_tenant): try: node_objects = get_objectlist_not_reserved_tenant(target_tenant) remove_ids = set() for node_id in retval: for obj in node_objects: #self._logger.debug('obj = %s' % obj) if int(node_id) == obj['id']: #self._logger.debug('obj = %s' % obj) remove_ids.add(node_id) break retval.difference_update(remove_ids) except Invalid_Key: retval = set() #log("end") #tenant end return generic.http_response( 200, 'Updated %s' % what.title(), **{"transaction": {'session_key': session_key, 'txid': '%.6f' % current_txid}, what: list(retval)})