[{"appcode":"/* \nFunction \"cron_impl_2func_651\" also requires \"cron_impl_2func_651_help\"\n\nCreate a basic cron system using Eventing allows a recurring function to execute activity at a \nspecified time every day, hour, min, 30 sec., and 15 sec. We use a bucket called 'crondata' \naliased to 'cron_bkt' which can hold one or more control documents of type = \"recurring_event\".\n\nThe following uses of timers do not work reliably in Couchbase versions 6.5 and 6.5.1\n a) scheduling an Eventing timer within a timer's callback \n b) overwriting an existing timer by id\n \nIn addition the ability to cancel a timer does not exist in Couchbase versions 6.5 and 6.5.1\n \nFor this example, we supply one real user function that builds a recurring 'static' cache document\nfrom bucket `travel-sample` via an N1QL query and save the result back to `travel-sample` via\nthe alais 'ts_bkt'. This JavaScript function is doCronActionA(), we also provide two placeholders\ndoCronActionB() and doCronActionC() for additional experimentation.\n\nTest Doc:\n {\n \"type\":\"recurring_event\", // The KEY will be <>::<>\n \"id\":1, //\n \"hour\":14, // The hour of the day 0-23, *, *2X, *4X to trigger\n \"min\":54, // The minute in the hour 0-59, *, *2X, *4X to trigger\n \"action\":\"doCronActionA\", // What function to run on the trigger\n \"active\":false, // Flag to arm or disable this schedule\n \"verbose\" : {\n \"user_func\":2, // Logging level for the action logic : 0=none, etc. etc.\n \"scheduler\":3 // Logging level for the cron logic : 0=none, etc. etc.\n },\n \"dynamic\" : {\n \"state\":\"arm\", // States \"arm\"|\"rearm\"|\"pending\" if any value but \"pending\" start a schedule\n \"next_sched\": 0, // Number of seconds since epoch to next desired schedule\n \"prev_sched\": 0, // Number of seconds since epoch for previous schedule\n \"prev_etime\": 0, // Number of seconds since epoch for previous schedule actual exec time\n \"prev_delay\": 0, // Number of seconds that the timer was delayed from the schedule\n \"prev_atime\": 0 // Number of seconds taken by the user 'action'\n }\n }\n \n INSERT INTO `crondata` (KEY,VALUE) VALUES (\"recurring_event::1\", \n {\n \"type\":\"recurring_event\",\n \"id\":1,\n \"hour\":14,\n \"min\":54,\n \"action\":\"doCronActionA\",\n \t\"verbose\" : {\n \"user_func\":2,\n \"scheduler\":3\n },\n \"active\":false,\n\t \"dynamic\" : {\n \"state\": \"arm\",\n \"next_sched\": 0,\n \"prev_sched\": 0,\n \"prev_etime\": 0,\n \"prev_delay\": 0,\n \"prev_atime\": 0\n\t }\n } \n );\n\nNote, you can omit verbose{} and dynamic{} as they will be auto-created by this main Eventing \nFunction \"cron_impl_2func_651\". If verbose{} is missing the logging levels will default to \nverbose\" : { \"user_func\":1, \"scheduler\":1 }\n\n INSERT INTO `crondata` (KEY,VALUE) VALUES (\"recurring_event::1\", \n {\n \"type\":\"recurring_event\",\n \"id\":1,\n \"hour\":14,\n \"min\":54,\n \"action\":\"doCronActionA\",\n \"active\":false\n } \n );\n\nN1QL : Make an index to query data without specifying keys\n CREATE primary INDEX on `crondata` ;\n\nN1QL : Verify or inspect settings in schedule\t \n SELECT * FROM `crondata` WHERE type=\"recurring_event\";\n\nN1QL : Arm or set active\t \n UPDATE `crondata` SET active = true WHERE type=\"recurring_event\" AND id=1 ;\n \nN1QL : Disarm or set inactive\t\n UPDATE `crondata` SET active = false WHERE type=\"recurring_event\" AND id=1 ;\n \nN1QL : Adjust time of trigger\t\n UPDATE `crondata` SET hour = 11, min = 30 WHERE type=\"recurring_event\" AND id=1 ;\n\nN1QL : Adjust logging\t \n UPDATE `crondata` SET verbose.user_func = 1, verbose.scheduler = 0 WHERE type=\"recurring_event\" AND id=1 ;\n\nN1QL : Delete the schedule\t \n DELETE FROM `crondata` WHERE type=\"recurring_event\" AND id=1 ;\n \nThe action field is important it 'should' exist in this Eventing Function note it could be any \nJavaScript name e.g. MyFunc and you must implement like the example doCronActionA(doc) where\ndoc will be the currently active item of type = 'recurring_event' read from the alias bucket\n‘cron_bkt’ when the timer is fired. The action JavaScript function should return either true\nor false used for logging purposes. If the action does not exist it is an error and a warning\nis logged and the timer is disabled.\n\nIn Couchbase version 6.5+ to add a new cron like daily function just pause the active handler \ninsert your new function doCronActionB(doc) {...} then Resume the eventing handler. The nice \nthing is if a timer was to be fired will the function was paused it will NOT be lost, when you \nresume the function it will be processed at the next available time slot. \n\nAny change to a control structure will create a new recurring schedule or timer and cancel the \ncurrent previous schedule this includes changing the verbosity level. The previous timer will \ncontinue to run however when executed it will do a Checksum on the current control structure \nfrom KV against it’s passed context and if different the Callback will ignore the old schedule.\nThis logic could be altered to process immediately if the schedule has expired search for the \nstring \"OnUpdate U\" in the code below.\n*/\n\n// ==================\n/* BEG USER FUNCTIONS TO RUN ONCE A DAY, HOUR, OR MINUTE - ANYTHING YOU WANT BELOW */\nfunction doCronActionA(doc) {\n try {\n // Check that doc has desired values\n if (!doc.type || doc.type !== \"recurring_event\" || !doc.active || doc.active !== true) return;\n if (doc.verbose.user_func >= 1)\n log(doc.action + ' user action controlled by ' + doc.type + '::' + doc.id);\n\n // this is a 6.5 N1QL query (feature not available in GA prior to 6.5)\n // Create an embedded N1QL iterator by issuing a SELECT statement to get the\n // counts of airlines by country. Make a new document and write it out to KV \n\n // We will use the iterator to create a KV document representing the results of a\n // HARD lengthy embedded N1QL query and write it back to KV, the idea is to keep\n // a calculation up to date once a day such that it that can be read 'quickly' \n // by other Eventing Functions, other Couchbase services or SDKs. \n\n // Consider if we had 1 million docs in a minute do we really want to use N1QL\n // to recalculate something that is almost static for all 1 million documents, of \n // course not, so we make an intermediate value that can be read into Eventing\n // and used via a single 'light weight' KV read.\n\n var q_iter = SELECT country,\n count( * ) cnt\n FROM `travel-sample`\n WHERE `type` = 'airline'\n GROUP BY country;\n\n // loop through the result set and update the map 'accumulate'\n var accumulate = {};\n var idx = 0;\n for (var val of q_iter) {\n if (doc.verbose.user_func >= 2)\n log(doc.action + ' N1QL idx ' + idx + ', country ' + val.country + \" cnt \" + val.cnt);\n accumulate[val.country] = val.cnt;\n idx++;\n }\n // close out embedded N1QL iterator\n q_iter.close();\n\n // Now let’s make a cached KV document representing a HARD length embedded N1QL\n // query and write it back to KV, we need a KEY and a type and id and then we \n // upsert it into the `travel-sample` bucket.\n\n var cachedoc = {};\n cachedoc.type = \"cron_cache\";\n cachedoc.id = \"airlines_by_country\";\n cachedoc.date = new Date();\n cachedoc.data = accumulate;\n var ckey = cachedoc.type + '::' + cachedoc.id;\n ts_bkt[ckey] = cachedoc;\n if (doc.verbose.user_func >= 2) {\n log(doc.action + ' upsert to KV with KEY ' + ckey + ' cachedoc ', cachedoc);\n }\n } catch (e) {\n log(doc.action + ' Error exception:', e);\n return false;\n }\n return true;\n}\n\nfunction doCronActionB(doc) {\n try {\n // check that doc has desired values\n if (doc.type !== \"recurring_event\" || doc.active !== true) return;\n if (doc.verbose.user_func >= 1)\n log(doc.action + ' user action controlled by ' + doc.type + '::' + doc.id);\n\n // YOUR LOGIC HERE\n\n } catch (e) {\n log(doc.action + ' Error exception:', e);\n return false;\n }\n return true;\n}\n\nfunction doCronActionC(doc) {\n try {\n // check that doc has desired values\n if (doc.type !== \"recurring_event\" || doc.active !== true) return;\n if (doc.verbose.user_func >= 1)\n log(doc.action + ' user action controlled by ' + doc.type + '::' + doc.id);\n\n // YOUR LOGIC HERE\n\n } catch (e) {\n log(doc.action + ' Error exception:', e);\n return false;\n }\n return true;\n}\n\n/* END USER FUNCTIONS TO RUN ONCE A DAY, HOUR, OR MINUTE - ANYTHING YOU WANT ABOVE */\n// ==================\n\n\n// FIXUP: ADDIN FUNCTON\nfunction noopTimer(context) {\n // fix for 6.5.X growing bucket ops\n try {\n if (context.type === \"_tmp_vbs\" && context.vb === 0) { \n // log(\"noopTimer timers firing, printing only for vBucket 0\");\n }\n } catch (e) {\n log(\"OnUpdate Exception in callback noopTimer:\", e);\n }\n}\n\n// FIXUP: ADDIN FUNCTON\nfunction rearmTimer(context) {\n // fix for 6.5.X growing bucket ops\n try {\n if (context.type === \"_tmp_vbs\" && context.vb === 0) { \n // Update/touch all docs in the helper_bucket the helper function will then\n // mutate all 1024 of type == vbs_seed (64 on MacOS) to create a recuring cycle.\n // log(\"noopTimer timer fired all 1024 vBuckets, logging only vb 0\", context);\n \n // generate a mutation to re-arm the HELPER function: fix_scan_issue\n // which will in turn make new mutations for this Function\n var cur = cron_bkt[context.key];\n if (cur && cur.ts_millis === context.ts_millis) {\n // log(\"rearmTimer update fix_timer_scan_issue::1 in helper_bucket alias only for vBucket 0\");\n var now = new Date();\n cron_bkt[\"fix_timer_scan_issue::1\"] = { \"last_update\": now };\n } else {\n // NOOP we had multiple timer cycles, just let this one quietly stop.\n }\n }\n } catch (e) {\n log(\"OnUpdate Exception in callback rearmTimer:\", e);\n }\n}\n\n// FIXUP: ADDIN FUNCTON\nfunction genNoopTimers(doc, meta, seconds) {\n // fix for 6.5.X growing bucket ops\n try {\n // redundant but play it safe\n if (doc.type === \"_tmp_vbs\") {\n // Since we are using an different function a timer on all our vBuckets do immeadiately (can take up to 15 seconds)\n // If we used cross bucket recursion to rearm all the timers in a recurring fashion we would add a delay of at least 40 seconds.\n createTimer(noopTimer, new Date(), null, doc);\n if (doc.vb === 0) { \n // Update/touch all docs in the helper_bucket the helper function will then\n // mutate all 1024 of type == vbs_seed (64 on MacOS) to create a recuring cycle.\n // log(\"noopTimer timer fired all 1024 vBuckets, logging only vb 0\", context);\n \n // generate a mutation to re-arm the HELPER function: fix_scan_issue\n // which will in turn make new mutations for this Function\n \n // log(\"genNoopTimers make timer to rearm fix_timer_scan_issue::1\");\n createTimer(rearmTimer, new Date(new Date().getTime() + seconds * 1000), null, doc);\n }\n }\n } catch (e) {\n log(\"OnUpdate Exception in genNoopTimers:\", e);\n }\n}\n\nfunction OnUpdate(doc, meta) {\n // fix for 6.5.X growing bucket ops\n if (doc.type === \"_tmp_vbs\") genNoopTimers(doc, meta, 30);\n if (!cron_bkt[\"fix_timer_scan_issue::1\"]) {\n cron_bkt[\"fix_timer_scan_issue::1\"] = {};\n }\n \n try {\n // Check if further analysis is needed we only trigger on an active recurring_event \n if (doc.type !== \"recurring_event\" || doc.active !== true) return;\n\n var update_doc = false;\n if (!doc.dynamic) {\n // Add if missing doc.dynamic with defaults\n doc.dynamic = {\n \"state\": \"arm\",\n \"next_sched\": 0,\n \"prev_sched\": 0,\n \"prev_etime\": 0,\n \"prev_delay\": 0,\n \"prev_atime\": 0\n };\n // we need to update the document once we have the next schedule\n update_doc = true;\n }\n if (!doc.verbose) {\n // Add if missing doc.dynamic with defaults\n doc.verbose = {\n \"user_func\": 1,\n \"scheduler\": 1\n };\n // we need to update the document once we have the next schedule\n update_doc = true;\n }\n // Do not process dynamic.state pending\n if (!doc.dynamic || !doc.dynamic.state || doc.dynamic.state === \"pending\") return;\n\n var mid = doc.type + \"::\" + doc.id; // this is the same as meta.id or the KEY\n var hour = doc.hour;\n var min = doc.min;\n\n // Do an eval check the JavaScript function exists. The eval occurs in a common \n // utility function shared with RecurringCallback\n if (!verifyFunctionExistsViaEval(doc, mid)) {\n // doc.action did not exist, we have already logged the issue\n return;\n }\n\n // Get the next valid execution time\n var date_timer = getNextRecurringDate(hour, min);\n var next_sched = Math.round(date_timer.getTime() / 1000);\n if (!update_doc && next_sched !== doc.dynamic.next_sched) {\n // the next_sched should be the same as the setting from the helper application, however\n // if we undeploy/deploy or pause/resume we might haver to reschedule to the next time slot\n log('OnUpdate U ' + mid + ' calculated next_sched !== doc.dynamic.next_sched, delta ' +\n (next_sched - doc.dynamic.next_sched) + ', reschedule');\n update_doc = true;\n }\n\n if (update_doc) {\n // this mutation is recursive and will be suppressed, we ensure we have a dynamic structure\n doc.dynamic.next_sched = next_sched;\n\n // rather then the call a function, to trap and retry if there is a resource issue\n // cron_bkt[mid] = doc;\n if (!tryBucketKvWriteWithLog('OnUpdate F', mid, doc)) {\n // Failed to write doc to cron_bkt[key] the error has been logged\n // and there is nothing more we can do.\n return;\n }\n }\n\n // Schedule an Eventing timer\n var timer_id = createTimer(Callback, date_timer, null, doc);\n if (doc.verbose.scheduler >= 1) {\n log('OnUpdate A ' + mid + ' rcv mutation (initial or rearm) schedule timer at ' +\n toLocalISOTime(date_timer));\n }\n if (doc.verbose.scheduler >= 2) {\n log('OnUpdate B ' + mid + ' recurring timer was created, timer_id ' + timer_id);\n }\n } catch (e) {\n log('OnUpdate E ' + meta.id + ', Error exception:', e);\n }\n}\n\nfunction getNextRecurringDate(hour_str, min_str) {\n // Note Javascript Dates are in milliseconds\n var date_now = new Date();\n var date_ret = new Date();\n var hour;\n var min;\n\n try {\n hour = parseInt(hour_str);\n } catch (e) {}\n try {\n min = parseInt(min_str);\n } catch (e) {}\n\n // Note, this is only a simplistic partial 'crontab' syntax with some slight extensions\n // it allows once a day, once an hour, once a minute. It also contains some non-standard \n // syntax to provide the ability to execute twice a minute or four times a minute.\n\n if (hour_str === '*4X' && min_str === '*4X') {\n // once every 15 seconds or four times a minute\n date_ret.setMilliseconds(0);\n date_ret.setSeconds(15);\n while (date_ret.getTime() < date_now.getTime()) {\n date_ret.setSeconds(date_ret.getSeconds() + 15);\n }\n return date_ret;\n } else\n if (hour_str === '*2X' && min_str === '*2X') {\n // once every 30 seconds or twice a minute\n date_ret.setMilliseconds(0);\n date_ret.setSeconds(30);\n while (date_ret.getTime() < date_now.getTime()) {\n date_ret.setSeconds(date_ret.getSeconds() + 30);\n }\n return date_ret;\n } else\n if (hour_str === '*' && min_str === '*') {\n // once a minute \n date_ret.setMilliseconds(0);\n date_ret.setSeconds(0);\n date_ret.setMinutes(date_ret.getMinutes() + 1);\n } else\n if (hour_str !== '*' && isNaN(hour) === false && min_str === '*') {\n // once a minute only for a given hour\n date_ret.setMilliseconds(0);\n date_ret.setSeconds(0);\n date_ret.setMinutes(date_ret.getMinutes() + 1);\n if (date_ret.getTime() < date_now.getTime()) {\n date_ret.setHours(hour);\n }\n if (date_ret.getTime() > date_now.getTime()) {\n date_ret.setDate(date_ret.getDate() + 1);\n date_ret.setSeconds(0);\n date_ret.setMinutes(0);\n date_ret.setHours(hour);\n }\n } else\n if (hour_str === '*' && min_str !== '*' && isNaN(min) === false) {\n // once a hour at a given minute\n date_ret.setMilliseconds(0);\n date_ret.setSeconds(0);\n date_ret.setMinutes(min);\n // schedule for next hour\n date_ret.setHours(date_ret.getHours() + 1);\n } else\n if (isNaN(hour) === false && isNaN(min) === false) {\n // once a day for a given hour and a given minute \n date_ret.setMilliseconds(0);\n date_ret.setSeconds(0);\n date_ret.setMinutes(min);\n date_ret.setHours(hour);\n if (date_ret.getTime() < date_now.getTime()) {\n // schedule for tomorrow\n date_ret.setDate(date_ret.getDate() + 1);\n }\n } else {\n log('getNextRecurringDate illegal input hour_str <' +\n hour_str + '> min_str <' + min_str + '>');\n throw new Error('getNextRecurringDate illegal input hour_str <' +\n hour_str + '> min_str <' + min_str + '>');\n return null;\n }\n return date_ret;\n}\n\nfunction verifyFunctionExistsViaEval(curDoc, id) {\n var result = false;\n try {\n // check for function if missing this is invalid return result\n result = eval(\"typeof \" + curDoc.action + \" === 'function';\");\n if (result === false) {\n if (curDoc.verbose.scheduler >= 1)\n log(\"Warn/Disable (No Action and No Re-Arm), because required 'action' of \" +\n curDoc.action + \"(doc) does not exist, id is\", id);\n return result;\n }\n } catch (e) {\n log('verifyFunctionExistsViaEval Error exception:', e);\n }\n return result;\n}\n\nfunction toNumericFixed(number, precision) {\n var multi = Math.pow(10, precision);\n return Math.round((number * multi).toFixed(precision + 1)) / multi;\n}\n\nfunction toLocalISOTime(d) {\n var tzoffset = (new Date()).getTimezoneOffset() * 60000; //offset in milliseconds\n return (new Date(d.getTime() - tzoffset)).toISOString().slice(0, -1);\n}\n\nfunction tryBucketKvWriteWithLog(tag, key, doc) {\n var success = false;\n var tries = 0;\n while (tries < 10) {\n tries++;\n try {\n // critical that the below succeeds, because if it doesn't the cron cycle will break\n cron_bkt[key] = doc;\n success = true;\n break;\n } catch (e) {\n log(tag + ' ' + key + ' WARN failed to update KV tries ' + tries, e);\n }\n }\n if (!success) {\n log(tag + ' ' + +key + ' FATAL could not update KV cron cycle, tried ' + tries + ', stoping ' + curDoc.action);\n }\n return success;\n}\n\nfunction Callback(doc) {\n try {\n var fired_at = new Date();\n\n // Check if further analysis is needed we only trigger on a recurring_event that is active\n if (doc.type !== \"recurring_event\") return;\n // doc must have 'action', 'dynamic {}', verbose {}, dynamic.state\n if (!doc.action || !doc.dynamic || !doc.verbose || !doc.dynamic.state) return;\n // process any doc.dynamic.state BUT pending \n if (doc.dynamic.state === \"pending\") return;\n\n // ==================\n // Check if still active\n\n // We make sure that in KV the 'doc' still exists and that it is still active if not just \n // return thus skipping the action and not Re-arming the timer. Note `travel-sample` is \n // aliased to the map 'cron_bkt\n\n var mid = doc.type + '::' + doc.id; // make our KEY\n var curDoc = null;\n try {\n // read the current version of doc from KV, e.g. curDoc\n curDoc = cron_bkt[mid];\n } catch (e) {} // needed for pre 6.5, note pure 6.5+ deployment returns null sans exception\n\n var reason = null;\n if (!curDoc || curDoc === null) {\n reason = \"cron document is missing\";\n } else\n if (!curDoc.active) {\n reason = \"cron document has active = false\";\n } else\n if (!curDoc.dynamic.state || curDoc.dynamic.state !== doc.dynamic.state) {\n reason = \"cron document wrong dynamic.state expected \" + doc.dynamic.state;\n } else\n if (crc64(doc) !== crc64(curDoc)) {\n reason = \"cron document changed\";\n }\n\n if (reason !== null) {\n if (!curDoc || curDoc === null || curDoc.verbose.scheduler >= 1) {\n log('Callback X ' + mid + \" ignore/stop this timer's schedule because \" + reason);\n }\n if (!curDoc || curDoc === null || curDoc.verbose.scheduler >= 4) {\n log('Callback Y ' + mid + ' timer doc', doc);\n log('Callback Z ' + mid + ' KV curDoc', curDoc);\n }\n return;\n }\n\n // ==================\n // Verify user routine exists and if so eval it \n\n // Assume curDoc.action contains something like \"doCronActionA\" and we have a function in \n // this handler like \"doCronActionA(doc)\". Below we use curDoc as the end user should be \n // able to alter the eval'd JavaScript function. We will execute two (2) evals.\n\n // First eval check the JavaScript function exists. The eval occurs in a common \n // utility function shared with RecurringCallback\n if (!verifyFunctionExistsViaEval(curDoc, mid)) {\n // curDoc.action did not exist, we have already logged the issue\n return;\n }\n\n // Second eval execute and process the user function we execute the defined function \n // with an argument of curDoc\n var beg_act = new Date();\n var result = null;\n eval(\"result = \" + curDoc.action + \"(curDoc);\");\n var end_act = new Date();\n var atime_ms = end_act.getTime() - beg_act.getTime();\n\n if (curDoc.verbose.scheduler >= 2)\n log('Callback R ' + mid + ' action took ' + toNumericFixed((atime_ms / 1000), 3) +\n ' sec., returned ' + result);\n\n // ==================\n // Calculate next time and mutate the control document for our our helper function\n // which will create another mutation such that OnUpdate of this function will pick\n // it up and generate the timer (avoids the MB-38554 issue).\n\n var hour = curDoc.hour;\n var min = curDoc.min;\n var date_timer = getNextRecurringDate(hour, min);\n\n curDoc.dynamic.prev_delay =\n toNumericFixed(((fired_at.getTime() / 1000) - curDoc.dynamic.next_sched), 3);\n curDoc.dynamic.prev_sched = curDoc.dynamic.next_sched;\n curDoc.dynamic.prev_etime = Math.round(fired_at.getTime() / 1000);\n curDoc.dynamic.prev_atime = toNumericFixed((atime_ms / 1000), 3);\n\n curDoc.dynamic.state = \"pending\";\n curDoc.dynamic.next_sched = Math.round(date_timer.getTime() / 1000);\n\n // rather then the call a function, to trap and retry if there is a resource issue\n // cron_bkt[mid] = curDoc;\n if (!tryBucketKvWriteWithLog('Callback F', mid, curDoc)) {\n // Failed to write curDoc to cron_bkt[key] the error has been logged\n // and there is nothing more we can do.\n return;\n }\n\n if (curDoc.verbose.scheduler >= 1) {\n log('Callback A ' + mid + ' gen mutation #1 to doc to force schedule rearm at ' +\n toLocalISOTime(date_timer));\n }\n if (curDoc.verbose.scheduler >= 2) {\n log('Callback B ' + mid + ' sched ' + curDoc.dynamic.prev_sched +\n ', actual ' + curDoc.dynamic.prev_etime +\n ', delay ' + curDoc.dynamic.prev_delay +\n ', took ' + curDoc.dynamic.prev_atime);\n }\n if (curDoc.verbose.scheduler >= 3) {\n log('Callback C ' + mid + ' curDoc', curDoc);\n }\n } catch (e) {\n var mid = doc.type + '::' + doc.id; // make our KEY\n log('Callback E ' + mid + ' Error exception:', e);\n }\n}","depcfg":{"buckets":[{"alias":"cron_bkt","bucket_name":"crondata","access":"rw"},{"alias":"ts_bkt","bucket_name":"travel-sample","access":"rw"}],"curl":[],"metadata_bucket":"metadata","source_bucket":"crondata"},"version":"evt-6.5.1-0000-ee","handleruuid":485537853,"id":0,"function_instance_id":"S6xOL","appname":"cron_impl_2func_651","settings":{"cluster_stats":null,"dcp_stream_boundary":"everything","deadline_timeout":62,"deployment_status":false,"description":"","execution_timeout":60,"language_compatibility":"6.5.0","log_level":"INFO","n1ql_consistency":"none","processing_status":false,"user_prefix":"eventing","using_timer":true,"worker_count":3},"using_timer":false,"src_mutation":true}]