{"id":103947,"date":"2024-09-20T00:12:18","date_gmt":"2024-09-20T00:12:18","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=103947"},"modified":"2024-09-20T00:12:19","modified_gmt":"2024-09-20T00:12:19","slug":"infinity-notebook-loop-in-fabric-using-data-activator","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/blogs\/infinity-notebook-loop-in-fabric-using-data-activator\/","title":{"rendered":"Infinity Notebook Loop in Fabric using Data Activator"},"content":{"rendered":"<p>Data Activator allow us to make an interesting workaround for infinity notebook executions.<\/p>\n<p>Infinity execution loop is interesting for constant data ingestion, but Fabric doesn&#8217;t allow an infinity loop inside a notebook, it ends up timing out and failing.<\/p>\n<p>Scheduling the notebook with very tight schedules is one possibility, but it&#8217;s not much trustworthy. You would need to know the precise run duration of the notebook and it&#8217;s not always the same. You end up with big intervals between the notebooks or with overlapping schedules. None of these options is good.<\/p>\n<p>There is an interesting alternative option we can use. Here comes the workaround.<\/p>\n<h2>The Architecture of the workaround<\/h2>\n<p>The solution is to create a sign if the notebook is running or not. We can do this using a control table. &#8220;Control table&#8221; is a regular table in a lakehouse, but we will use with the purpose to control the execution flow of the notebook.<\/p>\n<p>This table needs two fields: The date and time of the record insertion and an integer value which we will set to 0 or 1.<\/p>\n<p>The notebook we want to run needs to make an insert at the beginning of the execution and at the end. At the beginning we insert a record with the value 1, to points the notebook is executing. At the end, we insert a record with value 0.<\/p>\n<p>We can use Data Activator to monitor this table. Every time a record with value 0 is inserted, we execute the notebook again. In this way, Data Activator becomes the responsible for the infinity loop.<\/p>\n<h2>Ensuring the final Insert in the Table<\/h2>\n<p>It&#8217;s essential the final insert always executes at the end of the notebook, even if an error happens.<\/p>\n<p>If this final insert is not executed, the loop breaks. In this way, we need to use a <strong><em>try\/finally<\/em><\/strong> structure to ensure the final insert execution.<\/p>\n<pre class=\"lang:python decode:true \">try:\n     (main execution code)\nfinally:\n      (insert in control table)<\/pre>\n<p>The main execution code could be long. The best way to organize this execution is to break down the codes in functions. The main code structure ends up being simple: only the <strong><em>try\/finally<\/em><\/strong> exemplified above and calls to the functions which will make the actual work.<\/p>\n<p>This makes the core code quite simple.<\/p>\n<h2>Data Activator delay and the Notebook code<\/h2>\n<p>Data Activator has a 5 minutes delay to execute a trigger. We need always to consider this delay.<\/p>\n<p>You can extend to the maximum the intervals between the breaks by increasing the execution time of the notebook. I mean that the notebook itself can and should contain a loop of the execution.<\/p>\n<p>The notebook loop can&#8217;t be infinity, but you can extend to the maximum possible without making the execution instable. Data Activator will ensure the notebook will be executed again after it finishes.<\/p>\n<p>For example, I implemented scenarios where the notebook runs for 1 hour and 50 minutes. When it stops, it depends on data activator to be triggered again. In this way, every 1 hour and 50 minutes a 5 minutes interval can happen.<\/p>\n<h2>Configuring Data Activator<\/h2>\n<p>Data Activator requires one of the following to be configured:<\/p>\n<ul>\n<li>A real time ingestion EventStream<\/li>\n<li>A report visual<\/li>\n<li>A Kusto Query in a real time dashboard<\/li>\n<\/ul>\n<p>Considering the scenario we have, with a lakehouse table, I consider the best option the Kusto Query in a real time dashboard.<\/p>\n<p>I wrote before about how to use a <a href=\"https:\/\/www.red-gate.com\/simple-talk\/blogs\/microsoft-fabric-using-lakehouse-data-in-real-time-dashboards\/\" target=\"_self\" rel=\"noopener\">Kusto Database and shortcuts to allow lakehouses to use real time dashboards and data activator<\/a>.<\/p>\n<p>The main query is very simple, reading the data from the control table. The real time dashboard requires the query to use a time range filter to allow us to set the alert.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"581\" height=\"574\" class=\"wp-image-103948\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/09\/a-screenshot-of-a-computer-description-automatica-2.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<p>On the alert, we configure it to execute each time the value is set to 0.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"936\" height=\"189\" class=\"wp-image-103949\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/09\/a-screenshot-of-a-computer-description-automatica-3.png\" alt=\"A screenshot of a computer\n\nDescription automatically generated\" \/><\/p>\n<h2>Analyzing the execution time<\/h2>\n<p>An additional feature we get from this method is the possibility to analyze the execution times.<\/p>\n<ul>\n<li>The time difference from a record with value 1 to the next record with value 0 tells us the execution duration of the notebook.<\/li>\n<li>The difference from a record with value 0 to the next record with value 1 tells us the interval between 1 execution to another.<\/li>\n<\/ul>\n<p>Creating queries with these calculations we can build a dashboard to analyze the execution process.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1248\" height=\"335\" class=\"wp-image-103950\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2024\/09\/a-screenshot-of-a-graph-description-automatically.png\" alt=\"A screenshot of a graph\n\nDescription automatically generated\" \/><\/p>\n<h2>Summary<\/h2>\n<p>This is a very clever and reliable system for a continuous infinity execution. The only problem is the data activator interval, which may not be enough for some scenarios.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Data Activator allow us to make an interesting workaround for infinity notebook executions. Infinity execution loop is interesting for constant data ingestion, but Fabric doesn&#8217;t allow an infinity loop inside a notebook, it ends up timing out and failing. Scheduling the notebook with very tight schedules is one possibility, but it&#8217;s not much trustworthy. You&#8230;&hellip;<\/p>\n","protected":false},"author":50808,"featured_media":103951,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2,159160,159164],"tags":[159116,158997,101611,159114,159111],"coauthors":[6810],"class_list":["post-103947","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blogs","category-business-intelligence","category-microsoft-fabric","tag-data-activator","tag-microsoft-fabric","tag-power-bi","tag-real-time-dashboard","tag-real-time-intelligence"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/103947","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/50808"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=103947"}],"version-history":[{"count":1,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/103947\/revisions"}],"predecessor-version":[{"id":103952,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/103947\/revisions\/103952"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media\/103951"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=103947"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=103947"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=103947"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=103947"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}