def testBulkAdd(self): """Adds multiple tasks at once.""" taskqueue.Queue('test').add([ taskqueue.Task(url='/foo'), taskqueue.Task(url='/bar'), ])
def run_task(*args, **kwargs): pickled = cloudpickle.dumps((f, args, kwargs, extra)) logdebug("task pickle length: %s" % len(pickled)) if get_dump(): logdebug("f:") dumper(f) logdebug("args:") dumper(args) logdebug("kwargs:") dumper(kwargs) logdebug("extra:") dumper(extra) try: t = taskqueue.Task(payload=pickled, **task_kwargs) return t.add(queue, transactional=transactional) except taskqueue.TaskTooLargeError: if parent: key = _TaskToRun(data=pickled, parent=parent).put() else: key = _TaskToRun(data=pickled).put() ds_pickled = cloudpickle.dumps((None, [key], {}, { "_run_from_datastore": True })) t = taskqueue.Task(payload=ds_pickled, **task_kwargs) return t.add(queue, transactional=transactional)
def defer(obj, *args, **kwargs): """Defers a callable for execution later. The default deferred URL of /_ah/queue/deferred will be used unless an alternate URL is explicitly specified. If you want to use the default URL for a queue, specify _url=None. If you specify a different URL, you will need to install the handler on that URL (see the module docstring for details). Args: obj: The callable to execute. See module docstring for restrictions. _countdown, _eta, _headers, _name, _target, _transactional, _url, _queue: Passed through to the task queue - see the task queue documentation for details. args: Positional arguments to call the callable with. kwargs: Any other keyword arguments are passed through to the callable. Returns: A taskqueue.Task object which represents an enqueued callable. """ taskargs = dict((x, kwargs.pop(("_%s" % x), None)) for x in ("countdown", "eta", "name", "target")) taskargs["url"] = kwargs.pop("_url", _DEFAULT_URL) transactional = kwargs.pop("_transactional", False) taskargs["headers"] = dict(_TASKQUEUE_HEADERS) taskargs["headers"].update(kwargs.pop("_headers", {})) queue = kwargs.pop("_queue", _DEFAULT_QUEUE) pickled = serialize(obj, *args, **kwargs) try: task = taskqueue.Task(payload=pickled, **taskargs) return task.add(queue, transactional=transactional) except taskqueue.TaskTooLargeError: key = _DeferredTaskEntity(data=pickled).put() pickled = serialize(run_from_datastore, str(key)) task = taskqueue.Task(payload=pickled, **taskargs) return task.add(queue)
def add(self, queue_name, transactional=False, parent=None): """Add task to the queue.""" if self.compressed_payload is None: task = self.to_task() task.add(queue_name, transactional) return if len(self.compressed_payload) < self.MAX_TASK_PAYLOAD: task = taskqueue.Task( url=self.url, params={self.PAYLOAD_PARAM: self.compressed_payload}, name=self.name, eta=self.eta, countdown=self.countdown) task.add(queue_name, transactional) return if not parent: raise Exception("Huge tasks should specify parent entity.") payload_entity = _HugeTaskPayload(payload=self.compressed_payload, parent=parent) payload_key = payload_entity.put() task = taskqueue.Task( url=self.url, params={self.PAYLOAD_KEY_PARAM: str(payload_key)}, name=self.name, eta=self.eta, countdown=self.countdown) task.add(queue_name, transactional)
def report_to_bigquery(): """Flush all pending events of a certain type to BigQuery.""" # Schedule multiple flush jobs per minute for some events. if request.method == 'GET': tasks = [] for delay in xrange(0, 60, 5): tasks.append(taskqueue.Task(method='POST', url=request.path, countdown=delay, params={'event_name': 'content_vote_v1'})) tasks.append(taskqueue.Task(method='POST', url=request.path)) taskqueue.Queue(config.BIGQUERY_CRON_QUEUE_NAME).add(tasks) return '' # Retrieve pending events from pull queue. try: q = taskqueue.Queue(config.BIGQUERY_QUEUE_NAME) tasks = q.lease_tasks_by_tag(config.BIGQUERY_LEASE_TIME.total_seconds(), config.BIGQUERY_LEASE_AMOUNT, tag=flask_extras.get_parameter('event_name')) logging.debug('Leased %d event(s) from %s', len(tasks), config.BIGQUERY_QUEUE_NAME) except taskqueue.TransientError: logging.warning('Could not lease events due to transient error') return '', 503 if not tasks: return '' # Insert the events into BigQuery. table_id = tasks[0].tag rows = [json.loads(t.payload) for t in tasks] bigquery_client.insert_rows(table_id, rows) # Delete the tasks now that we're done with them. q.delete_tasks(tasks) return ''
def put(self): logging.debug(self.request.body) body = self.readJson() trace = body.get("trace") application = body.get("application") timestamp = body.get("timestamp") queue = taskqueue.Queue(name='count') task = taskqueue.Task( url='/application', target='counter', payload="{\"application\": \"%s\", \"timestamp\": \"%s\"}" % (application, timestamp), method="PUT") rpc = queue.add_async(task) rpcs = [] lines = trace.split(" at ") lines.pop(0) pattern = re.compile('at (.+)\(') for f in lines: # f = match.group(0) task = taskqueue.Task( url='/function', target='counter', payload="{\"function\": \"%s\", \"timestamp\": \"%s\"}" % (f, timestamp), method="PUT") rpcs.append(queue.add_async(task)) rpc.get_result() for rpc in rpcs: rpc.get_result() self.SendJsonOKMessage('Analyze done, update tasks queued')
def testFiltering(self): taskqueue.Task(name='task_one', url='/url/of/task/1/').add('queue-1') taskqueue.Task(name='task_two', url='/url/of/task/2/').add('queue-2') # All tasks tasks = self.taskqueue_stub.get_filtered_tasks() assert len(tasks) == 2 # Filter by name tasks = self.taskqueue_stub.get_filtered_tasks(name='task_one') assert len(tasks) == 1 assert tasks[0].name == 'task_one' # Filter by URL tasks = self.taskqueue_stub.get_filtered_tasks(url='/url/of/task/1/') assert len(tasks) == 1 assert tasks[0].name == 'task_one' # Filter by queue tasks = self.taskqueue_stub.get_filtered_tasks(queue_names='queue-1') assert len(tasks) == 1 assert tasks[0].name == 'task_one' # Multiple queues tasks = self.taskqueue_stub.get_filtered_tasks( queue_names=['queue-1', 'queue-2']) assert len(tasks) == 2
def testFiltering(self): taskqueue.Task(name='task_one', url='/url/of/task/1/').add('queue-1') taskqueue.Task(name='task_two', url='/url/of/task/2/').add('queue-2') # All tasks tasks = self.taskqueue_stub.get_filtered_tasks() self.assertEqual(len(tasks), 2) # Filter by name tasks = self.taskqueue_stub.get_filtered_tasks(name='task_one') self.assertEqual(len(tasks), 1) self.assertEqual(tasks[0].name, 'task_one') # Filter by URL tasks = self.taskqueue_stub.get_filtered_tasks(url='/url/of/task/1/') self.assertEqual(len(tasks), 1) self.assertEqual(tasks[0].name, 'task_one') # Filter by queue tasks = self.taskqueue_stub.get_filtered_tasks(queue_names='queue-1') self.assertEqual(len(tasks), 1) self.assertEqual(tasks[0].name, 'task_one') # Multiple queues tasks = self.taskqueue_stub.get_filtered_tasks( queue_names=['queue-1', 'queue-2']) self.assertEqual(len(tasks), 2)
def runtask(*args, **kwargs): pickled = cloudpickle.dumps((f, args, kwargs, passthroughargs)) logdebug("task pickle length: %s" % len(pickled)) if get_dump(): logdebug("f:") dumper(f) logdebug("args:") dumper(args) logdebug("kwargs:") dumper(kwargs) logdebug("passthroughargs:") dumper(passthroughargs) try: task = taskqueue.Task(payload=pickled, **taskkwargscopy) return task.add(queue, transactional=transactional) except taskqueue.TaskTooLargeError: pickledf = cloudpickle.dumps(f) pickleda = cloudpickle.dumps(args) pickledk = cloudpickle.dumps(kwargs) pickledp = cloudpickle.dumps(passthroughargs) logexception( "task too large, need to use datastore (%s, %s, %s, %s)" % (len(pickledf), len(pickleda), len(pickledk), len(pickledp))) if parent: key = _TaskToRun(data=pickled, parent=parent).put() else: key = _TaskToRun(data=pickled).put() rfspickled = cloudpickle.dumps((None, [key], {}, { "_run_from_datastore": True })) task = taskqueue.Task(payload=rfspickled, **taskkwargscopy) return task.add(queue, transactional=transactional)
def test_OverQuotaError(self): message = "30秒後にトップページへ移動します" error_message = "サーバーエラーが発生しました。トップページを表示しています。" queue = taskqueue.Queue("cache") assert [i.tag for i in queue.lease_tasks(0, 1000)] == [] response = self.app.get("/test/test.html", headers={"User-Agent": "bot"}, status=503) assert response.headers.get("Retry-After") == "86400" response = self.app.get("/test/test.html", status=500) response.mustcontain(message) response.mustcontain("<meta content='30; url=/' http-equiv='refresh'>") assert error_message not in response self.app.get("/sample/") self.execute_tasks("default") caches = queue.lease_tasks_by_tag(0, 1000, tag="localhost:80/sample/") assert len(caches) == 1 payload = caches[0].payload queue.add( taskqueue.Task(method="PULL", tag="/index.html", payload=payload)) queue.delete_tasks(caches) assert [i.tag for i in queue.lease_tasks(0, 1000)] == ["/index.html"] response = self.app.get("/test/test.html", status=500) response.mustcontain(message) response.mustcontain("<meta content='30; url=/' http-equiv='refresh'>") assert error_message not in response queue.add(taskqueue.Task(method="PULL", tag="/", payload=payload)) assert [i.tag for i in queue.lease_tasks(0, 1000)] == ["/index.html", "/"] response = self.app.get("/test/test.html", status=500) assert message not in response response.mustcontain(error_message)
def prep(search_params=None, **kw): if search_params is None: return if 'filters' not in search_params: return filters = search_params['filters'] if len(filters) != 1: return filter = filters[0] if 'name' not in filter: return if filter['name'] != 'scholar_id': return if filter['op'] != '==': return scholar_id = filter['val'] publication = Publication.query.filter_by(scholar_id=scholar_id).first() if (publication is None or publication.retrieved_at is None): queue = taskqueue.Queue('publication-fetchers') task = taskqueue.Task(url='/publication/crawl', params={'scholar_id': scholar_id}) queue.add(task) raise ProcessingException(description='Try later.', code=202) elif (datetime.now() - publication.retrieved_at).days > 365: queue = taskqueue.Queue('publication-fetchers') task = taskqueue.Task(url='/publication/crawl', params={'scholar_id': scholar_id}) queue.add(task)
def __notify_feature_subscribers_of_changes(self, is_update): """Async notifies subscribers of new features and property changes to features by posting to a task queue.""" # Diff values to see what properties have changed. changed_props = [] for prop_name, prop in self.properties().iteritems(): new_val = getattr(self, prop_name, None) old_val = getattr(self, '_old_' + prop_name, None) if new_val != old_val: changed_props.append({ 'prop_name': prop_name, 'old_val': old_val, 'new_val': new_val}) payload = json.dumps({ 'changes': changed_props, 'is_update': is_update, 'feature': self.format_for_template(version=2) }) # Create task to email subscribers. queue = taskqueue.Queue()#name='emailer') task = taskqueue.Task(method="POST", url='/tasks/email-subscribers', target='notifier', payload=payload) queue.add(task) # Create task to send push notifications queue = taskqueue.Queue() task = taskqueue.Task(method="POST", url='/tasks/send_notifications', target='notifier', payload=payload) queue.add(task)
def testAddingTasks(self): """Tests for adding tasks.""" taskqueue.add(url='/run') taskqueue.Queue('test').add(taskqueue.Task(url='/foo')) self.assertRaises(taskqueue.UnknownQueueError, taskqueue.Queue('unknown').add, taskqueue.Task(url='/foo'))
def post(self): """In this task, we should watch an episode entity and check the task queue for the new completed episode. then, create a new task to send the email. """ # TODO 1: in the first run, we shoul defer it for later, because if # there were no task pending, it will be instantly trigguered :( keyEpisode = self.request.get('keyEpisode') submitter = self.request.get('submitter') # get the episode from the database # check if this episode has videos. (Trick for the earliest version) # TODO: check if all this episode videos have been added or failed # by now, just check if video queue is empty queue = taskqueue.Queue() # get the queue of newVideos queueStats = queue.fetch_statistics() # returns QueueStatistics if queueStats.tasks == 0: logging.debug("There are no pending video tasks") # so send an email sender = "Capitulizer Mighty Bot <*****@*****.**>" to = submitter # send them to the submitter TODO cc = "" # by now, empty string so sending doesnt fail #bcc = "*****@*****.**" # and send a copy to the admin subject = "New Episode Available to Watch" # TODO 1: create the notification body body = """<html><h1>Notification Email Body</h1> http://capitulizer.appspot.com/</html>""" # New version, creating a new task logging.debug("Creating task sendEmail") queue = taskqueue.Queue('sendEmail') task = taskqueue.Task(url='/tasks/sendEmail', params={ 'sender': sender, 'subject': subject, 'body': body, 'cc': cc, 'bcc': bcc, 'to': to }) queue.add(task) logging.debug("Creating task newPost") queue = taskqueue.Queue('newPost') task = taskqueue.Task(url='/tasks/newPost', params={'keyEpisode': keyEpisode}) queue.add(task) else: logging.debug("There are still some video tasks to complete") # so retry raise Exception("Still new videos waiting. Maybe next time...")
def _defer(queues, func, funcArgs, funcKwargs, countdown=None, eta=None, taskName=None, target=None, transactional=False, retry_options=None, parent=None): """ Our own implementation of deferred.defer. This allows: - using webapp2 as deferred handler and applying our middlewares - using task asynchronous API - using cPickle instead of pickle - logging headers at DEBUG level instead of INFO """ payload = _serialize(func, funcArgs, funcKwargs) queueName = random.choice(queues) # We track which function is called so that it appears clearly in the App admin dash-board. # Note: if it's a class method, we only track the method name and not the class name. url = "/_cb/deferred/%s/%s" % (getattr(func, '__module__', ''), getattr(func, '__name__', '')) headers = {"Content-Type": "application/octet-stream"} try: task = taskqueue.Task(payload=payload, target=target, url=url, headers=headers, countdown=countdown, eta=eta, name=taskName, retry_options=retry_options) except taskqueue.TaskTooLargeError: logging.info('Task Too Large. Storing payload in the data store') key = yield _DeferredTaskEntity(data=payload, parent=parent).put_async() payload = _serialize(_run_from_datastore, [key], {}) task = taskqueue.Task(payload=payload, target=target, url=url, headers=headers, countdown=countdown, eta=eta, name=taskName, retry_options=retry_options) ret = yield task.add_async(queueName, transactional=transactional) raise ndb.Return(ret)
def test_batches_get_split_TombstonedTaskError(self, queue_add_mock): """Ensure a batches get split and retried on TombstonedTaskErrors.""" from furious.context.context import _insert_tasks from google.appengine.api import taskqueue def raise_error(*args, **kwargs): raise taskqueue.TombstonedTaskError() queue_add_mock.side_effect = raise_error tasks = (taskqueue.Task('A'), taskqueue.Task('1'), taskqueue.Task('B')) inserted = _insert_tasks(tasks, 'AbCd') self.assertEqual(5, queue_add_mock.call_count) self.assertEqual(0, inserted)
def test_batches_get_split_TransientError(self, queue_add_mock, mock_sleep): """Ensure TransientErrors retries once, and correctly returns the number of inserted tasks.""" from furious.context.context import _insert_tasks from google.appengine.api import taskqueue queue_add_mock.side_effect = (taskqueue.TransientError, None) tasks = (taskqueue.Task('A'), taskqueue.Task('1'), taskqueue.Task('B')) inserted = _insert_tasks(tasks, 'AbCd') self.assertEqual(2, queue_add_mock.call_count) self.assertEqual(3, inserted) self.assertEqual(mock_sleep.call_count, 1)
def post(self): _msg = self.request.get('message', '0') if _msg is not None: sentOn = None _type = self.request.get('type', '') post_args = self.request.arguments() if _type in ['feedback', 'error-feedback']: if 'reportsentutc' in post_args: sentOn = self.parseDateTime( self.request.get('reportsentutc', '')) _groupId = long(self.request.get('groupid', '')) if _groupId and sentOn: if _msg != 'Automatically sent': fb = Feedback(groupId=_groupId, sendTime=sentOn, timezone=self.request.get( 'reportsenttz', ''), type=_type, message=_msg) fb.put() q = taskqueue.Queue('feedback-export-queue') q.add((taskqueue.Task(payload=fb.getExportLine(), method='PULL'))) Cnt.incr("Feedback_counter") else: logging.warning( 'Automatically sent feedback message, discarding.') self.response.out.write("OK") else: self.error(400) else: self.error(400) else: self.error(400)
def to_task(self): """Convert to a taskqueue task without doing any kind of encoding.""" return taskqueue.Task(url=self.url, params=self.params, name=self.name, eta=self.eta, countdown=self.countdown)
def cron_run_import(): # pragma: no cover """Schedules a push task for each config set imported from Gitiles.""" conf = admin.GlobalConfig.fetch() # Collect the list of config sets to import. config_sets = [] if (conf and conf.services_config_storage_type == GITILES_STORAGE_TYPE and conf.services_config_location): loc = gitiles.Location.parse_resolve(conf.services_config_location) config_sets += _service_config_sets(loc) config_sets += _project_and_ref_config_sets() # For each config set, schedule a push task. # This assumes that tasks are processed faster than we add them. tasks = [ taskqueue.Task(url='/internal/task/luci-config/gitiles_import/%s' % cs) for cs in config_sets ] q = taskqueue.Queue('gitiles-import') pending = tasks while pending: batch = pending[:100] pending = pending[len(batch):] q.add(batch) logging.info('scheduled %d tasks', len(tasks))
def get(self): self.response.headers['Content-Type'] = 'text/plain' task = taskqueue.Task(url='/worker', params={'foo': 'bar'}) task.add( # must be something other than default to trigger bug: queue_name='background-processing') self.response.out.write('Hello world!')
def create_videos_tasks(self, linksInter=[], keyEpisode=""): try: # create newVideo tasks to add videos to the episode. limit = 30 # TODO eliminate this limit. is horrible, sucker #if we want to set a limit, we should do it better # with the interlinks, get some data for linkInter in linksInter: # TODO: rename linkInter to interLink limit -= 1 # build a link if its not complete linkInter = extract.buildLink(linkInter) # and dont get past the limit if limit > 0: # Call a newVideo task for each interlink queue = taskqueue.Queue('newVideo') task = taskqueue.Task(url='/tasks/newVideo', params={ 'keyEpisode': keyEpisode, 'interLink': linkInter }) queue.add(task) else: logging.error("We still have a limit set") break except: raise # TODO
def tick(request): queue = taskqueue.Queue('challenges-sendemails') task = taskqueue.Task(url='/challenges/send_challenge_emails', method='GET') queue.add(task) return HttpResponse(json.dumps({'status': 'ok'}), content_type='application/json')
def post(self): if not self.request.body: self.response.write("Bad request.") self.response.status_int = 400 return dna = json.loads(self.request.body) if not self.valid_dna(dna.get('dna')): self.response.write("Bad request.") self.response.status_int = 400 return is_mutant = Human.is_mutant(dna.get('dna')) queue = taskqueue.Queue(name='default') task = taskqueue.Task(url='/insert_dna/', target='worker', params={ 'dna': dna, 'is_mutant': is_mutant }) queue.add(task) if is_mutant: self.response.write('It is mutant.') else: self.response.write("Is human.") self.response.status_int = 403
def manual_process_for_venue(venue_id): raise DeprecationWarning( 'this code is now depricated as it relies on the depricated InstagramDataProcessor' ) logging.debug("SPICE: socialnetworks/instagram/process_for_venue started") if instagram_settings.instagram_auto_process_callback == False: instagram_queue = taskqueue.Queue('instagramcallback') queue_stats = instagram_queue.fetch_statistics() # Only add if there is no task in the queue if queue_stats.tasks < 1: task = taskqueue.Task( url= '/socialengine/api/instagram/callback_task?key=%s&venue_id=%s' % (spice_settings.static_api_key, venue_id), method='GET') instagram_queue.add(task) logging.debug( "SPICE: socialnetworks/instagram/process_for_venue added task for venue_id %s" % venue_id) logging.debug("SPICE: socialnetworks/instagram/process_for_venue ended") return None
def delete(self): queue_name = self.request.get('queueName') task_id = self.request.get('taskId') queue = taskqueue.Queue(queue_name) task = taskqueue.Task(name=task_id) queue.delete_tasks(task)
def AuthorizedPost(self): datastore_hooks.SetPrivilegedRequest() with timing.WallTimeLogger('decompress'): try: data_str = self.request.body zlib.decompress(data_str) logging.info('Recieved compressed data.') except zlib.error: data_str = self.request.get('data') data_str = zlib.compress(data_str) logging.info('Recieved uncompressed data.') if not data_str: raise api_request_handler.BadRequestError( 'Missing "data" parameter') filename = uuid.uuid4() params = {'gcs_file_path': '/add-histograms-cache/%s' % filename} gcs_file = cloudstorage.open(params['gcs_file_path'], 'w', content_type='application/octet-stream', retry_params=_RETRY_PARAMS) gcs_file.write(data_str) gcs_file.close() retry_options = taskqueue.TaskRetryOptions( task_retry_limit=_TASK_RETRY_LIMIT) queue = taskqueue.Queue('default') queue.add( taskqueue.Task(url='/add_histograms/process', payload=json.dumps(params), retry_options=retry_options))
def EnqueueTasks(tasks, task_tag): """Enqueues a list of tasks in the Google Cloud task queue, for consumption by Google Compute Engine. """ q = taskqueue.Queue('clovis-queue') # Add tasks to the queue by groups. # TODO(droger): This supports thousands of tasks, but maybe not millions. # Defer the enqueuing if it times out. group_size = 100 callbacks = [] try: for i in range(0, len(tasks), group_size): group = tasks[i:i + group_size] taskqueue_tasks = [ taskqueue.Task(payload=task.ToJsonString(), method='PULL', tag=task_tag) for task in group ] rpc = taskqueue.create_rpc() q.add_async(task=taskqueue_tasks, rpc=rpc) callbacks.append(rpc) for callback in callbacks: callback.get_result() except Exception as e: clovis_logger.error('Exception:' + type(e).__name__ + ' ' + str(e.args)) return False clovis_logger.info('Pushed %i tasks with tag: %s.' % (len(tasks), task_tag)) return True
def testGetTaskHostDefaultModule(self): os.environ["CURRENT_MODULE_ID"] = "default" self.assertEqual("v7.foo.appspot.com", util._get_task_host()) task = taskqueue.Task(url="/relative_url", headers={"Host": util._get_task_host()}) self.assertEqual("v7.foo.appspot.com", task.headers["Host"]) self.assertEqual("v7", task.target)
def reschedule(cls, base_path, mapreduce_spec, serial_id, queue_name=None): """Schedule new update status callback task. Args: base_path: mapreduce handlers url base path as string. mapreduce_spec: mapreduce specification as MapreduceSpec. serial_id: id of the invocation as int. queue_name: The queue to schedule this task on. Will use the current queue of execution if not supplied. """ task_name = ControllerCallbackHandler.get_task_name( mapreduce_spec, serial_id) task_params = ControllerCallbackHandler.controller_parameters( mapreduce_spec, serial_id) if not queue_name: queue_name = os.environ.get("HTTP_X_APPENGINE_QUEUENAME", "default") controller_callback_task = taskqueue.Task( url=base_path + "/controller_callback", name=task_name, params=task_params, countdown=_CONTROLLER_PERIOD_SEC) if not _run_task_hook(mapreduce_spec.get_hooks(), "enqueue_controller_task", controller_callback_task, queue_name): try: controller_callback_task.add(queue_name) except (taskqueue.TombstonedTaskError, taskqueue.TaskAlreadyExistsError), e: logging.warning( "Task %r with params %r already exists. %s: %s", task_name, task_params, e.__class__, e)