<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>aklefdal&#39;s tech blog</title>
    <link>https://aklefdal.com/</link>
    <description>Recent content on aklefdal&#39;s tech blog</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <lastBuildDate>Mon, 17 Mar 2025 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://aklefdal.com/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Password-less access from pipeline to database</title>
      <link>https://aklefdal.com/2025/03/password-less-access-from-pipeline-to-db/</link>
      <pubDate>Mon, 17 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://aklefdal.com/2025/03/password-less-access-from-pipeline-to-db/</guid>
      <description>&lt;h2 id=&#34;the-goal&#34;&gt;The goal&lt;/h2&gt;&#xA;&lt;p&gt;The goal is to be able to run database migrations as part of a Azure DevOps Pipeline with using a stored secret anywhere. The databases are Azure Sql Databases, connected to a VNET, with no public access. There are two major problems to solve:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Network access&lt;/li&gt;&#xA;&lt;li&gt;Authentication&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;background&#34;&gt;Background&lt;/h2&gt;&#xA;&lt;p&gt;My current project is at a company with a software solution that has been in development for more than 20 years. Traditionally it ran on-premise, that is at the customer&amp;rsquo;s site. This is still the case for a few customers, but most customers are now using the service served from a cloud-hosted solution - Software-as-a-Service - SaaS&lt;/p&gt;</description>
    </item>
    <item>
      <title>Generate a sequence of DateOnly in F#</title>
      <link>https://aklefdal.com/2024/12/generate-a-sequence-of-dateonly-in-f/</link>
      <pubDate>Sun, 29 Dec 2024 00:00:00 +0000</pubDate>
      <guid>https://aklefdal.com/2024/12/generate-a-sequence-of-dateonly-in-f/</guid>
      <description>&lt;p&gt;For a hobby project I had to generate a sequence of &lt;code&gt;DateTime&lt;/code&gt; (a.k.a. &lt;code&gt;IEnumerable&amp;lt;DateTime&amp;gt;&lt;/code&gt;).&lt;/p&gt;&#xA;&lt;p&gt;Generating a sequence from simple types is easy:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-f#&#34; data-lang=&#34;f#&#34;&gt;let seqOfInt (start: int) (end: int) =&#xA;    seq { start .. end }&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But we cannot use range operator with DateOnly:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-f#&#34; data-lang=&#34;f#&#34;&gt;// Not valid code!&#xA;let badSeqOfDateTime (startDate: DateOnly) (endDate: DateOnly) =&#xA;    seq { startDate .. endDate }&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In my first attempt at this (and current code as of today), I ended up with a while loop and a mutable:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Query Azure Table Storage using F#</title>
      <link>https://aklefdal.com/2024/12/query-azure-table-storage-using-f/</link>
      <pubDate>Sun, 29 Dec 2024 00:00:00 +0000</pubDate>
      <guid>https://aklefdal.com/2024/12/query-azure-table-storage-using-f/</guid>
      <description>&lt;p&gt;When looking at the signature of the &lt;a href=&#34;https://learn.microsoft.com/en-us/dotnet/api/azure.data.tables.tableclient.queryasync?view=azure-dotnet&#34;&gt;TableClient.QueryAsync&lt;/a&gt; method in Azure.Data.Tables SDK, it is not clear how to use it. It returns a &lt;a href=&#34;https://learn.microsoft.com/en-us/dotnet/api/azure.asyncpageable-1?view=azure-dotnet&#34;&gt;&lt;code&gt;AsyncPageable&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/a&gt;. Fortunately that again implements the &lt;a href=&#34;https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.iasyncenumerable-1?view=net-9.0&#34;&gt;&lt;code&gt;IAsyncEnumerable&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/a&gt;, which means that we can use the Fsharp.Control.TaskSeq library to get the resulting entities.&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Install &lt;a href=&#34;https://www.nuget.org/packages/FSharp.Control.TaskSeq&#34;&gt;FSharp.Control.TaskSeq&lt;/a&gt; NuGet-package to your project.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;code&gt;open FSharp.Control&lt;/code&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Write your code using the &lt;code&gt;TaskSeq&lt;/code&gt; module&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-f#&#34; data-lang=&#34;f#&#34;&gt;let getPartitionRows (tableClient: TableClient) (partition: string) =&#xA;    task {&#xA;        return!&#xA;            tableClient.QueryAsync&amp;lt;TableEntity&amp;gt;(filter = $&amp;#34;PartitionKey eq &amp;#39;{partition}&amp;#39;&amp;#34;)&#xA;            |&amp;gt; TaskSeq.map fromEntity&#xA;            |&amp;gt; TaskSeq.toArrayAsync&#xA;    }&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is written as a reminder to myself, so that I can easily find it again&lt;/p&gt;</description>
    </item>
    <item>
      <title>Great improvement of build times</title>
      <link>https://aklefdal.com/2012/12/great-improvement-of-build-times/</link>
      <pubDate>Sun, 30 Dec 2012 00:00:00 +0000</pubDate>
      <guid>https://aklefdal.com/2012/12/great-improvement-of-build-times/</guid>
      <description>&lt;p&gt;The two last days I presented the &lt;a href=&#34;https://aklefdal.com/2012/12/painful-development-cycle-rebuild-and-run-unit-tests-in-4-minutes/&#34;&gt;organization of our solution&lt;/a&gt;, and did &lt;a href=&#34;https://aklefdal.com/2012/12/moving-code-to-common-projects/&#34;&gt;some improvements&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Next up in the refactorings is to move the service implementations to the same project as the services themselves. They will always be deployed together, so there is no need to keep them in separate assemblies. Each service implementation project contains only one small class, so this is an easy refactoring.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;images/ServicesSolutionafterServiceImplementations_thumb.png&#34; alt=&#34;ServicesSolution after ServiceImplementations&#34; title=&#34;ServicesSolution after ServiceImplementations&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;This shaved off another 9 projects and 5-10 seconds of the build time, and we are down to 65-75 seconds.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Moving code to common projects</title>
      <link>https://aklefdal.com/2012/12/moving-code-to-common-projects/</link>
      <pubDate>Sat, 29 Dec 2012 00:00:00 +0000</pubDate>
      <guid>https://aklefdal.com/2012/12/moving-code-to-common-projects/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://aklefdal.com/2012/12/painful-development-cycle-rebuild-and-run-unit-tests-in-4-minutes/&#34;&gt;Yesterday&lt;/a&gt; I talked about our current setup, Today I will start to refactor away projects.&lt;/p&gt;&#xA;&lt;p&gt;First up is to combine all the ServiceContracts-projects to one common ServiceContract-project&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;images/ServicesSolutionafterServiceContracts_thumb.png&#34; alt=&#34;ServicesSolution after ServiceContracts&#34; title=&#34;ServicesSolution after ServiceContracts&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;This reduced the build time from 90-100 seconds to 80-90 seconds. Not much, and maybe not enough to be statistically significant.&lt;/p&gt;&#xA;&lt;p&gt;Next up was to combine all the Services-projects to one common Services project.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;images/ServicesSolutionafterServices_thumb.png&#34; alt=&#34;ServicesSolution after Services&#34; title=&#34;ServicesSolution after Services&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Painful development cycle &amp;ndash; rebuild and run unit tests in 4 minutes</title>
      <link>https://aklefdal.com/2012/12/painful-development-cycle-rebuild-and-run-unit-tests-in-4-minutes/</link>
      <pubDate>Fri, 28 Dec 2012 00:00:00 +0000</pubDate>
      <guid>https://aklefdal.com/2012/12/painful-development-cycle-rebuild-and-run-unit-tests-in-4-minutes/</guid>
      <description>&lt;p&gt;This Christmas I’m going try out improving the development environment at my current project. The baseline is as follows.&lt;/p&gt;&#xA;&lt;p&gt;The project is big and has been running for years. Previously they have been working on the parts of the systems that the customers use through a web solutions, and the parts that the customer-facing employees use.&lt;/p&gt;&#xA;&lt;p&gt;The part I am working on now was started fairly recently, and consists of the core system, which mainly run in the background using batch jobs, and providing services for the other parts of the system. This is what I will be talking about here.&lt;/p&gt;</description>
    </item>
    <item>
      <title>What is ACM?</title>
      <link>https://aklefdal.com/2012/06/what-is-acm/</link>
      <pubDate>Fri, 22 Jun 2012 00:00:00 +0000</pubDate>
      <guid>https://aklefdal.com/2012/06/what-is-acm/</guid>
      <description>&lt;p&gt;June 6 the company I work for, &lt;a href=&#34;https://www.computas.com/&#34;&gt;Computas&lt;/a&gt;, was selected as &lt;a href=&#34;https://adaptivecasemanagement.org/awards_2012_winners.html&#34;&gt;Gold Winner in Global Awards for Excellence in Adaptive Case Management&lt;/a&gt; hosted by the &lt;a href=&#34;https://www.wfmc.org/&#34;&gt;Workflow Management Coalition&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;ACM stands for Adaptive Case Management. It is an evolution of &lt;a href=&#34;http://en.wikipedia.org/wiki/Business_process_management&#34;&gt;BPM&lt;/a&gt; (Business Process Management), or maybe a response to that concept. Its foundation is process management for knowledge workers. The characteristics of knowledge work is that it is unpredictable, and that you select what to do based on your knowledge, not on a predefined process.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
