<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Stephen's Website</title>
    <link href="https://sglmr.com/subscribe/blog/atom.xml" rel="self" />
    <link href="https://sglmr.com/" />
    <updated>2026-04-17T00:00:00+00:00</updated>
    <author>
        <name>Stephen</name>
    </author>
    <id>https://sglmr.com/</id>
    
    <entry>
        <title>PixelWolf 88x31 Button Generator</title>
        <link href="https://sglmr.com/blog/pixelwolf-88x31-button-generator/" />
        <id>https://sglmr.com/blog/pixelwolf-88x31-button-generator/</id>
        <updated>2026-04-17T00:00:00+00:00</updated>
        <summary type="html">&lt;p&gt;After trying out a bunch of 88x31 button generators, this one was the easiest to create a few quick, lightweight buttons.&lt;/p&gt;</summary>
    </entry>
    
    <entry>
        <title>How the CEO of Obsidian uses Obsidian</title>
        <link href="https://sglmr.com/blog/obsidian-ceo-vault/" />
        <id>https://sglmr.com/blog/obsidian-ceo-vault/</id>
        <updated>2026-04-08T00:00:00+00:00</updated>
        <summary type="html">&lt;p&gt;How the CEO of Obsidian uses his own note taking application.&lt;/p&gt;</summary>
    </entry>
    
    <entry>
        <title>Concrete Laptop Stand</title>
        <link href="https://sglmr.com/blog/concrete-stand/" />
        <id>https://sglmr.com/blog/concrete-stand/</id>
        <updated>2026-04-07T00:00:00+00:00</updated>
        <summary type="html">&lt;p&gt;This is pretty cool. I like the project and process more than the aesthetic.&lt;/p&gt;</summary>
    </entry>
    
    <entry>
        <title>Single page calendar</title>
        <link href="https://sglmr.com/blog/single-page-calendar/" />
        <id>https://sglmr.com/blog/single-page-calendar/</id>
        <updated>2026-04-06T00:00:00+00:00</updated>
        <summary type="html">&lt;p&gt;A single page calendar.&lt;/p&gt;
&lt;p&gt;This version was inspired by &lt;a href=&#34;https://neatnik.net/calendar/&#34;&gt;https://neatnik.net/calendar/&lt;/a&gt;. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Demo: &lt;a href=&#34;https://abetusk.github.io/neatocal/&#34;&gt;https://abetusk.github.io/neatocal/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Source: &lt;a href=&#34;https://github.com/abetusk/neatocal&#34;&gt;https://github.com/abetusk/neatocal&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</summary>
    </entry>
    
    <entry>
        <title>Blogosphere</title>
        <link href="https://sglmr.com/blog/blogosphere/" />
        <id>https://sglmr.com/blog/blogosphere/</id>
        <updated>2026-04-03T00:00:00+00:00</updated>
        <summary type="html">&lt;p&gt;What&#39;s old is new again. A nice spot to find content by (hopefully) real people.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Side note: I wish Facebook, Instagram, and all the others were more interested in building connections with friends, family, and my community than squeeze every possible moment of my attention out of me.&lt;/em&gt;&lt;/p&gt;</summary>
    </entry>
    
    <entry>
        <title>Django health status notifications with ntfy.sh</title>
        <link href="https://sglmr.com/blog/ntfy-django-status/" />
        <id>https://sglmr.com/blog/ntfy-django-status/</id>
        <updated>2026-04-02T00:00:00+00:00</updated>
        <summary type="html">&lt;p&gt;There are a gazillion ways to get status notifications for a web application, but here&#39;s another one using ntfy.sh&lt;/p&gt;
&lt;p&gt;This little helper function would need to be scheduled to run in a task queue like &lt;a href=&#34;https://django-q2.readthedocs.io&#34;&gt;django-q2&lt;/a&gt;. It could also be modified slightly into a cron job.&lt;/p&gt;
&lt;div class=&#34;highlight&#34; style=&#34;background: #f8f8f8&#34;&gt;&lt;pre style=&#34;line-height: 125%;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span style=&#34;color: #008000; font-weight: bold&#34;&gt;def&lt;/span&gt;&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color: #00F&#34;&gt;ntfy_status&lt;/span&gt;() &lt;span style=&#34;color: #666&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span style=&#34;color: #008000&#34;&gt;str&lt;/span&gt;:
&lt;span style=&#34;color: #BBB&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color: #BA2121; font-style: italic&#34;&gt;&amp;quot;&amp;quot;&amp;quot;Checks the health check endpoint and sends a notification to ntfy.sh.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span style=&#34;color: #008000; font-weight: bold&#34;&gt;import&lt;/span&gt;&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color: #00F; font-weight: bold&#34;&gt;requests&lt;/span&gt;
    &lt;span style=&#34;color: #008000; font-weight: bold&#34;&gt;from&lt;/span&gt;&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color: #00F; font-weight: bold&#34;&gt;django.contrib.sites.models&lt;/span&gt;&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color: #008000; font-weight: bold&#34;&gt;import&lt;/span&gt; Site
    &lt;span style=&#34;color: #008000; font-weight: bold&#34;&gt;from&lt;/span&gt;&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color: #00F; font-weight: bold&#34;&gt;django.urls&lt;/span&gt;&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color: #008000; font-weight: bold&#34;&gt;import&lt;/span&gt; reverse

    &lt;span style=&#34;color: #008000; font-weight: bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color: #A2F; font-weight: bold&#34;&gt;not&lt;/span&gt; settings&lt;span style=&#34;color: #666&#34;&gt;.&lt;/span&gt;NTFY_TOPIC:
        &lt;span style=&#34;color: #008000; font-weight: bold&#34;&gt;raise&lt;/span&gt; &lt;span style=&#34;color: #CB3F38; font-weight: bold&#34;&gt;ValueError&lt;/span&gt;(&lt;span style=&#34;color: #BA2121&#34;&gt;&amp;quot;NTFY_TOPIC environment variable is not configured.&amp;quot;&lt;/span&gt;)

    &lt;span style=&#34;color: #3D7B7B; font-style: italic&#34;&gt;# Create the full url to a health check&lt;/span&gt;
    protocol &lt;span style=&#34;color: #666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color: #BA2121&#34;&gt;&amp;quot;https&amp;quot;&lt;/span&gt; &lt;span style=&#34;color: #008000; font-weight: bold&#34;&gt;if&lt;/span&gt; settings&lt;span style=&#34;color: #666&#34;&gt;.&lt;/span&gt;SECURE_SSL_REDIRECT &lt;span style=&#34;color: #008000; font-weight: bold&#34;&gt;else&lt;/span&gt; &lt;span style=&#34;color: #BA2121&#34;&gt;&amp;quot;http&amp;quot;&lt;/span&gt;
    domain &lt;span style=&#34;color: #666&#34;&gt;=&lt;/span&gt; Site&lt;span style=&#34;color: #666&#34;&gt;.&lt;/span&gt;objects&lt;span style=&#34;color: #666&#34;&gt;.&lt;/span&gt;get_current()&lt;span style=&#34;color: #666&#34;&gt;.&lt;/span&gt;domain
    path &lt;span style=&#34;color: #666&#34;&gt;=&lt;/span&gt; reverse(&lt;span style=&#34;color: #BA2121&#34;&gt;&amp;quot;health_check&amp;quot;&lt;/span&gt;)
    url &lt;span style=&#34;color: #666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color: #BA2121&#34;&gt;f&amp;quot;&lt;/span&gt;&lt;span style=&#34;color: #A45A77; font-weight: bold&#34;&gt;{&lt;/span&gt;protocol&lt;span style=&#34;color: #A45A77; font-weight: bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color: #BA2121&#34;&gt;://&lt;/span&gt;&lt;span style=&#34;color: #A45A77; font-weight: bold&#34;&gt;{&lt;/span&gt;domain&lt;span style=&#34;color: #A45A77; font-weight: bold&#34;&gt;}{&lt;/span&gt;path&lt;span style=&#34;color: #A45A77; font-weight: bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color: #BA2121&#34;&gt;&amp;quot;&lt;/span&gt;

    health_response &lt;span style=&#34;color: #666&#34;&gt;=&lt;/span&gt; requests&lt;span style=&#34;color: #666&#34;&gt;.&lt;/span&gt;get(url)

    &lt;span style=&#34;color: #008000; font-weight: bold&#34;&gt;if&lt;/span&gt; health_response&lt;span style=&#34;color: #666&#34;&gt;.&lt;/span&gt;status_code &lt;span style=&#34;color: #666&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color: #666&#34;&gt;200&lt;/span&gt;:
        emoji &lt;span style=&#34;color: #666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color: #BA2121&#34;&gt;&amp;quot;green_circle&amp;quot;&lt;/span&gt;
        suffix &lt;span style=&#34;color: #666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color: #BA2121&#34;&gt;&amp;quot;is up!&amp;quot;&lt;/span&gt;
    &lt;span style=&#34;color: #008000; font-weight: bold&#34;&gt;else&lt;/span&gt;:
        emoji &lt;span style=&#34;color: #666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color: #BA2121&#34;&gt;&amp;quot;red_circle,skull&amp;quot;&lt;/span&gt;
        suffix &lt;span style=&#34;color: #666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color: #BA2121&#34;&gt;&amp;quot;is down!&amp;quot;&lt;/span&gt;

    &lt;span style=&#34;color: #3D7B7B; font-style: italic&#34;&gt;# Send ntfy message&lt;/span&gt;
    ntfy_response &lt;span style=&#34;color: #666&#34;&gt;=&lt;/span&gt; requests&lt;span style=&#34;color: #666&#34;&gt;.&lt;/span&gt;post(
        &lt;span style=&#34;color: #BA2121&#34;&gt;f&amp;quot;https://ntfy.sh/&lt;/span&gt;&lt;span style=&#34;color: #A45A77; font-weight: bold&#34;&gt;{&lt;/span&gt;settings&lt;span style=&#34;color: #666&#34;&gt;.&lt;/span&gt;NTFY_TOPIC&lt;span style=&#34;color: #A45A77; font-weight: bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color: #BA2121&#34;&gt;&amp;quot;&lt;/span&gt;,
        data&lt;span style=&#34;color: #666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color: #BA2121&#34;&gt;f&amp;quot;&lt;/span&gt;&lt;span style=&#34;color: #A45A77; font-weight: bold&#34;&gt;{&lt;/span&gt;domain&lt;span style=&#34;color: #A45A77; font-weight: bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color: #BA2121&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color: #A45A77; font-weight: bold&#34;&gt;{&lt;/span&gt;suffix&lt;span style=&#34;color: #A45A77; font-weight: bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color: #BA2121&#34;&gt;&amp;quot;&lt;/span&gt;,
        headers&lt;span style=&#34;color: #666&#34;&gt;=&lt;/span&gt;{
            &lt;span style=&#34;color: #BA2121&#34;&gt;&amp;quot;Tags&amp;quot;&lt;/span&gt;: &lt;span style=&#34;color: #BA2121&#34;&gt;f&amp;quot;&lt;/span&gt;&lt;span style=&#34;color: #A45A77; font-weight: bold&#34;&gt;{&lt;/span&gt;emoji&lt;span style=&#34;color: #A45A77; font-weight: bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color: #BA2121&#34;&gt;,&lt;/span&gt;&lt;span style=&#34;color: #A45A77; font-weight: bold&#34;&gt;{&lt;/span&gt;health_response&lt;span style=&#34;color: #666&#34;&gt;.&lt;/span&gt;status_code&lt;span style=&#34;color: #A45A77; font-weight: bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color: #BA2121&#34;&gt;&amp;quot;&lt;/span&gt;,
            &lt;span style=&#34;color: #BA2121&#34;&gt;&amp;quot;Actions&amp;quot;&lt;/span&gt;: &lt;span style=&#34;color: #BA2121&#34;&gt;&amp;quot;view, Open URL, &lt;/span&gt;&lt;span style=&#34;color: #A45A77; font-weight: bold&#34;&gt;{url}&lt;/span&gt;&lt;span style=&#34;color: #BA2121&#34;&gt;, clear=true&amp;quot;&lt;/span&gt;,
        },
    )

    ntfy_response&lt;span style=&#34;color: #666&#34;&gt;.&lt;/span&gt;raise_for_status()
    &lt;span style=&#34;color: #008000; font-weight: bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color: #BA2121&#34;&gt;&amp;quot;Sent notification to ntfy.sh with status code: &amp;quot;&lt;/span&gt; &lt;span style=&#34;color: #666&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color: #008000&#34;&gt;str&lt;/span&gt;(ntfy_response&lt;span style=&#34;color: #666&#34;&gt;.&lt;/span&gt;status_code)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;img alt=&#34;Notification screenshot&#34; src=&#34;/assets/media/2026/ntfy-django-status-screenshot.jpeg&#34;&gt;&lt;/p&gt;</summary>
    </entry>
    
    <entry>
        <title>I ran a half marathon! 🏃</title>
        <link href="https://sglmr.com/blog/first-half-marathon-report/" />
        <id>https://sglmr.com/blog/first-half-marathon-report/</id>
        <updated>2026-03-21T00:00:00+00:00</updated>
        <summary type="html">&lt;p&gt;I don&#39;t think anyone else will ever read or see this, but it was a lot of work; and 6 months ago, I didn&#39;t think I could do it. &lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;Finish line on the warning track&#34; src=&#34;/assets/media/2026/shamrockn-half-marathon-2026-finish-line.jpeg&#34;&gt;&lt;/p&gt;
&lt;p&gt;My goal was just to finish. Based on my training runs, it looked like I might run a 2:45:00 time, but I beat it by about 30 minutes. I was trying to run by heart rate, but it felt boringly slow. A few miles in, I switched to a 90s/30s run walk and it carried me through the end of the race.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;/assets/media/2026/shamrockn-half-marathon-2026-finisher.jpeg&#34;&gt;&lt;/p&gt;
&lt;p&gt;Lesson&#39;s learned:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A half marathon is very do-able.&lt;/li&gt;
&lt;li&gt;Nature&#39;s Bakery fig bars are decent real food option for runs.&lt;/li&gt;
&lt;li&gt;I drink a lot of water and it was VERY helpful to keep a 500 mL bottle of Skratch with me in a belt during the run.&lt;/li&gt;
&lt;li&gt;The Galloway run walk method was amazing! I think the run would have been a lot harder and slower without it.&lt;/li&gt;
&lt;/ul&gt;</summary>
    </entry>
    
    <entry>
        <title>The difference between worry, anxiety, and stress</title>
        <link href="https://sglmr.com/blog/worrying-well-ness-labs/" />
        <id>https://sglmr.com/blog/worrying-well-ness-labs/</id>
        <updated>2026-03-19T00:00:00+00:00</updated>
        <summary type="html">&lt;p&gt;&lt;a href=&#34;https://nesslabs.com/worrying-well&#34;&gt;Worrying well: how to bring wisdom to your worries&lt;/a&gt; by Anne-Laure Le Cunff&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Worrying well is about tapping into the wisdom of real or imagined people, you can turn your negative worry into a positive one—whether a worry you accept, if the circumstances are out of your control, or one you can take action upon.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Worry.&lt;/strong&gt; A repetitive/ruminative form of thinking about the future or the past.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Anxiety.&lt;/strong&gt; An uncomfortable feeling of fear, apprehension, or dread, often in the gut or chest, accompanied by physical symptoms such as rapid heartbeat and sweating.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Stress.&lt;/strong&gt; A physical response (fight or flight) to a threat, real or imagined.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;</summary>
    </entry>
    
    <entry>
        <title>Workday Compensation Plan Assignments Security gotcha</title>
        <link href="https://sglmr.com/blog/workday-compensation-by-organization-security/" />
        <id>https://sglmr.com/blog/workday-compensation-by-organization-security/</id>
        <updated>2026-03-06T00:00:00+00:00</updated>
        <summary type="html">&lt;p&gt;I hit another Workday security &#34;gotcha&#34; today.&lt;/p&gt;
&lt;p&gt;I needed a field that was based on a related business object &#34;Compensation Plan Assignments&#34;.&lt;/p&gt;
&lt;p&gt;No problem, &lt;em&gt;Related Actions &amp;gt;&amp;gt; View Security for Calculated Field&lt;/em&gt;. Okay, &lt;code&gt;View&lt;/code&gt; access on &lt;code&gt;Worker Data: Compensation by Organization&lt;/code&gt;, great.&lt;/p&gt;
&lt;p&gt;And it didn&#39;t work! I was stuck for the better part of an hour.&lt;/p&gt;
&lt;p&gt;Eventually I came up with the correct search encantation to find something helpful on Workday Community:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://workday.my.site.com/customercenter/article?no=000006862&amp;amp;redirect=false&#34;&gt;Report User Or ISU Not Seeing Merit, Bonus Or Stock Plan Assignment Data&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Issue&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A report user or ISU account is not seeing merit, bonus or stock plan assignment data.&lt;/p&gt;
&lt;p&gt;For example &lt;em&gt;Compensation Plan Assignment&lt;/em&gt; related fields, secured by the &lt;em&gt;Worker Data: Compensation by Organization&lt;/em&gt; domain, are not returning the expected merit, bonus or stock plan assignment data.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cause&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In line with your Organizations compensation security model please verify if access is also required on the &lt;em&gt;Worker Data: Funded Plan Assignments&lt;/em&gt; domain:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Worker Data: Funded Plan Assignments&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Domain description: &lt;em&gt;This domain works in conjunction with segment security to provide the ability to secure funded plan (merit, bonus or stock) assignments.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Resolution&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Grant the user access to the applicable &lt;em&gt;Worker Data: Funded Plan Assignments&lt;/em&gt; domain.  Activate changes and retest.&lt;/p&gt;
&lt;p&gt;Example impacted fields:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Compensation Plan Assignment&lt;/li&gt;
&lt;li&gt;Merit Plans - Plan Details&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;</summary>
    </entry>
    
    <entry>
        <title>Workday Studio &#34;exit()&#34;</title>
        <link href="https://sglmr.com/blog/exit-workday-studio/" />
        <id>https://sglmr.com/blog/exit-workday-studio/</id>
        <updated>2026-02-16T00:00:00+00:00</updated>
        <summary type="html">&lt;p&gt;Today I learned there is an MVEL expression do do a &#34;System.exit&#34; or &#34;sys.exit()&#34; in Workday Studio.&lt;/p&gt;
&lt;div class=&#34;highlight&#34; style=&#34;background: #f8f8f8&#34;&gt;&lt;pre style=&#34;line-height: 125%;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;context.&lt;span style=&#34;color: #687822&#34;&gt;setAbort&lt;/span&gt;(&lt;span style=&#34;color: #008000; font-weight: bold&#34;&gt;true&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;: The default behavior of all local-out steps is &lt;code&gt;Propogate Abort = true&lt;/code&gt;.  Generally you&#39;ll want this. If the abort isn&#39;t working as expected, check that setting first.&lt;/p&gt;
&lt;h1&gt;Example&lt;/h1&gt;
&lt;h2&gt;1. Set an integration time limit&lt;/h2&gt;
&lt;p&gt;Somewhere near the beginning of the integration, set a time limit on the integration.&lt;/p&gt;
&lt;div class=&#34;highlight&#34; style=&#34;background: #f8f8f8&#34;&gt;&lt;pre style=&#34;line-height: 125%;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span style=&#34;color: #3D7B7B; font-style: italic&#34;&gt;// You could simply set a global value&lt;/span&gt;
props&lt;span style=&#34;color: #666&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color: #BA2121&#34;&gt;&amp;quot;runtimeLimitHours&amp;quot;&lt;/span&gt;&lt;span style=&#34;color: #666&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color: #666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color: #666&#34;&gt;3.9&lt;/span&gt;

&lt;span style=&#34;color: #3D7B7B; font-style: italic&#34;&gt;// OR you could retrieve it from a launch parameter or integration attribute&lt;/span&gt;
props&lt;span style=&#34;color: #666&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color: #BA2121&#34;&gt;&amp;quot;runtimeLimitHours&amp;quot;&lt;/span&gt;&lt;span style=&#34;color: #666&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color: #666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;Double.&lt;span style=&#34;color: #687822&#34;&gt;valueOf&lt;/span&gt;(lp.&lt;span style=&#34;color: #687822&#34;&gt;getSimpleData&lt;/span&gt;(&lt;span style=&#34;color: #BA2121&#34;&gt;&amp;quot;Runtime Limit (hours)&amp;quot;&lt;/span&gt;));
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;If you use a launch parameter or integration attribute, consider adding an &lt;strong&gt;ValidateExp&lt;/strong&gt; that the value is between 0 and 4 hours&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;2: Evaluate the run duration&lt;/h2&gt;
&lt;p&gt;So for example, say you&#39;re in a loop processing a few thousand records. After the splitter, you might have an &lt;strong&gt;eval&lt;/strong&gt; component with something like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34; style=&#34;background: #f8f8f8&#34;&gt;&lt;pre style=&#34;line-height: 125%;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span style=&#34;color: #3D7B7B; font-style: italic&#34;&gt;// 1. Get the current time and the &amp;#39;sent&amp;#39; time in milliseconds&lt;/span&gt;
&lt;span style=&#34;color: #B00040&#34;&gt;long&lt;/span&gt;&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;nowMs&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color: #666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;System.&lt;span style=&#34;color: #687822&#34;&gt;currentTimeMillis&lt;/span&gt;();
&lt;span style=&#34;color: #B00040&#34;&gt;long&lt;/span&gt;&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;sentMs&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color: #666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;lp.&lt;span style=&#34;color: #687822&#34;&gt;sentOnAsDate&lt;/span&gt;.&lt;span style=&#34;color: #687822&#34;&gt;getTime&lt;/span&gt;();

&lt;span style=&#34;color: #3D7B7B; font-style: italic&#34;&gt;// 2. Calculate the difference in milliseconds&lt;/span&gt;
&lt;span style=&#34;color: #B00040&#34;&gt;long&lt;/span&gt;&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;diffMs&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color: #666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;nowMs&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color: #666&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;sentMs;

&lt;span style=&#34;color: #3D7B7B; font-style: italic&#34;&gt;// 3. Convert to hours as a double (to support decimals like 3.75)&lt;/span&gt;
&lt;span style=&#34;color: #3D7B7B; font-style: italic&#34;&gt;// There are 3,600,000 milliseconds in one hour&lt;/span&gt;
&lt;span style=&#34;color: #B00040&#34;&gt;double&lt;/span&gt;&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;diffHours&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color: #666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;diffMs&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color: #666&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color: #666&#34;&gt;3600000.0&lt;/span&gt;;

&lt;span style=&#34;color: #3D7B7B; font-style: italic&#34;&gt;// 4. Logic check&lt;/span&gt;
&lt;span style=&#34;color: #008000; font-weight: bold&#34;&gt;if&lt;/span&gt;&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;(diffHours&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color: #666&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;props&lt;span style=&#34;color: #666&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color: #BA2121&#34;&gt;&amp;quot;runtimeLimitHours&amp;quot;&lt;/span&gt;&lt;span style=&#34;color: #666&#34;&gt;]&lt;/span&gt;)&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;{
&lt;span style=&#34;color: #BBB&#34;&gt;    &lt;/span&gt;&lt;span style=&#34;color: #3D7B7B; font-style: italic&#34;&gt;// Logic for when the time limit is exceeded&lt;/span&gt;
&lt;span style=&#34;color: #BBB&#34;&gt;    &lt;/span&gt;props&lt;span style=&#34;color: #666&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color: #BA2121&#34;&gt;&amp;quot;abortIntegration&amp;quot;&lt;/span&gt;&lt;span style=&#34;color: #666&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color: #666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color: #008000; font-weight: bold&#34;&gt;true&lt;/span&gt;;
}&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color: #008000; font-weight: bold&#34;&gt;else&lt;/span&gt;&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;{
&lt;span style=&#34;color: #BBB&#34;&gt;    &lt;/span&gt;props&lt;span style=&#34;color: #666&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color: #BA2121&#34;&gt;&amp;quot;abortIntegration&amp;quot;&lt;/span&gt;&lt;span style=&#34;color: #666&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color: #666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color: #008000; font-weight: bold&#34;&gt;false&lt;/span&gt;;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;3. Route by duration&lt;/h2&gt;
&lt;p&gt;Then you could have a &lt;strong&gt;route&lt;/strong&gt; step that checks &lt;code&gt;props[&#34;abortIntegration&#34;]&lt;/code&gt; for each record.  The &lt;em&gt;choose-route&lt;/em&gt; expression would be something like:&lt;/p&gt;
&lt;div class=&#34;highlight&#34; style=&#34;background: #f8f8f8&#34;&gt;&lt;pre style=&#34;line-height: 125%;&#34;&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span style=&#34;color: #3D7B7B; font-style: italic&#34;&gt;// abort&lt;/span&gt;
(&lt;span style=&#34;color: #B00040&#34;&gt;boolean&lt;/span&gt;)props&lt;span style=&#34;color: #666&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color: #BA2121&#34;&gt;&amp;quot;abortIntegration&amp;quot;&lt;/span&gt;&lt;span style=&#34;color: #666&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color: #666&#34;&gt;==&lt;/span&gt;&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color: #008000; font-weight: bold&#34;&gt;true&lt;/span&gt;

&lt;span style=&#34;color: #3D7B7B; font-style: italic&#34;&gt;// continue&lt;/span&gt;
(&lt;span style=&#34;color: #B00040&#34;&gt;boolean&lt;/span&gt;)props&lt;span style=&#34;color: #666&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color: #BA2121&#34;&gt;&amp;quot;abortIntegration&amp;quot;&lt;/span&gt;&lt;span style=&#34;color: #666&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color: #666&#34;&gt;==&lt;/span&gt;&lt;span style=&#34;color: #BBB&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color: #008000; font-weight: bold&#34;&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;4. Handle the abort&lt;/h2&gt;
&lt;p&gt;The last thing in the logic path will be an &lt;strong&gt;eval&lt;/strong&gt; step with &lt;code&gt;context.setAbort(true)&lt;/code&gt;. Do any steps to close out the integration before the &lt;code&gt;context.setAbort&lt;/code&gt;. So for example, there might be steps like:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Log a &lt;code&gt;CRTICICAL&lt;/code&gt; message in a &lt;strong&gt;PutIntegrationMessage&lt;/strong&gt; step&lt;/li&gt;
&lt;li&gt;Close/save any log files with a &lt;strong&gt;local-out&lt;/strong&gt; step&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;eval&lt;/strong&gt; step to trigger the abort with &lt;code&gt;context.setAbort(true)&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;</summary>
    </entry>
    
</feed>