Thursday, August 31, 2017

August Cycling

Up to 14706.3, 942.9, 213.1 = 19.4 + 160.7 + 6.8 == 186.9 (YTD 1504 miles), slightly less than last month, with the weather staying less than summery up to almost the end of the month (and an unusually hot dry Bank Holiday Monday). The basic 4x40 miles/week commute was the backbone, with some side trips on the other bikes, mostly business, only one being a "stretch my legs on a summer afternoon" leisure ride.

Wednesday, August 02, 2017

July Cycling

Up to 14686.9, 782.2, 206.3 = 0 + 143.9 + 43.4 = 187.3 (YTD 1317 miles), in a month where the summer weather ended early, and where rides on holiday being instead of, rather than in addition to, the miles I normally commute in a week.

Peddars Way

As you can tell from the photo, the weather was already on the way downhill in the second week of the month, leading up to our driving home in the rain on St Swithin's Day.

Saturday, July 01, 2017

June Cycling

Up to 14686.9, 638.3, 162.9 = 31 + 177.4 + 20.8 = 229.2 (YTD 1130 miles), in a dry and not too windy month. One long bike-ride, going the pretty way to the shops, but the rest is mostly business (including road-testing maintenance like putting a new chain and new tyres on the winter bike).

Wednesday, June 07, 2017


Elegant little lady

Gone at the age of just 14 months.

She had been out and roaming for much of the spring, home only for meals and bed-time, so I didn't find occasion for cute cat pictures of her, unlike her tree-climbing brother. Only anecdotes, like the time just a week or so ago when the local nuisance muntjac was wandering down the close, and then headed down one of the driveways -- then a little black scrap that had been watching scampered in apparent pursuit. And memories of her leaping up and sprawling on my lap, just a little featherweight who shed handfuls of fur when I combed her.

Sunday, she didn't turn up for supper, but did join the feeding frenzy for the bribe of wet food to come in for the night. Monday, she was not the only one who didn't get out of their basket when I went out early to work, but was looking a bit peaky. When I came home she had found somewhere to hide where I couldn't see her, so I feared for the worse. Again, she emerged late evening, to use the litter tray, but this time showed little interest in food, and was clearly unsteady on her feet.

So, off to the vets, with a fever and dehydration; and it turned out over the last couple of months, she had started to lose weight. Being such a small and fluffy cat compared with the others, and having a healthy appetite but without begging for more, it hadn't been obvious until just a few days ago. The blood tests showed that her white cell count was low, and after she had been relaxed with pain relief, they found a lump in her abdomen. She responded a bit to to rehydration, but her condition deteriorated over night.

Thursday, June 01, 2017

May Cycling

Up to 14655.9, 460.9, 142.1 = 186.9 miles (YTD 901 miles), so a bit up on the previous month, in what ended up rather pleasant weather. No long bike rides for fun, not even the long way around to work, though, as more time got spent in the garden again.

Friday, May 05, 2017

Chunked Enumerable revisited (in F#)

Revisiting an old post on the subject, prompted by a recent question on the MSDN Visual F# forum.

Despite it being a very common thing to want to do, to process a stream of data in blocks, there isn't a library function for it yet; and it's not something that can be put together in a functional form using the pieces we have in the Collections.Seq module. Either, as in my earlier attempts, we have to go into object-land, with intrusions into the implementation details of enumerations (and their disposal), and eager evaluation at best; or we have to go imperative/procedural to get full lazy evaluation as per the code buried within the this C# example.

For idiomatic F#, we don't want an extension method, but a stand-alone function which we can chain into the usual pipeline of |> operations, so we would translate it thus —

where we bury the imperative/mutable kernel, the place where we count the number of steps we take (or stop early when we hit the end of the input), inside an inner function.

Monday, May 01, 2017

April Cycling

Up to 14655.9, 274.0, 142.1 = 173.2 miles, which is about the same as the monthly rate I averaged over Q1 (YTD 714 miles). Way down on last year; I didn't even keep up the 30 Days challenge, as the 4th was wet in the afternoon/early evening. When we have had good weather, I've been more inclined to work in the garden, where it's sheltered from the rather chill winds that characterised most of the month or get things done around the house; and it's less draining to start early, drive, finish early than cycle, work, cycle, work some more, cook. What rain we have had in a generally dry month also managed to skew towards driving and staying dry on days where I might normally have cycled; and these days, the chance to stop in town on the way home has reduced the need or incentive to cycle into town at weekends.

Saturday, April 01, 2017

March Cycling

Up to 14655.9, 148.8, 142.1 = 193.6 miles + ~90 off-meter = 284, which is better than January and February combined (YTD 541 miles), with more commuting and shopping by bike, and in the good weather at the end of the month, another quick CycleBreaks holiday and the first days of cycling with bare arms for the year (even if a chill easterly kept bringing in haze from the North Sea).

Sunday, being the day after the clocks went even an early start was late by the clock, and being Mothering Sunday to boot, finding lunch as well as the usual getting the saddle height just right and getting used to the bike meant I ended up doing a fairly short ride, during which time the cloud and wind picked up, and encouraged me back to base. Monday started grey, but by the time I'd gone most of the way through Ipswich the sun was burning through, so I could take the jacket off for the full circuit of Alton Water and then back again. Tuesday was misty until late morning, but I managed a ride out to Snape and back after it started to clear, with a pit-stop at the Elephant and Castle in Eyke on the way back.

Without an on-board measure this time, I estimated the journeys on Google Maps, and it was quite a surprise to find that the "short" ride to Snape and back was about the same distance as the "long" loop of Alton Water that took me about 50% longer in terms of time in the saddle.

Tuesday, February 28, 2017

February Cycling

Up to 14625.1, 0, 128.1 -- 147.6 miles, which is better than January, since I did manage to average more than one day a week commuting by bike, and the weather has at times felt positively spring-like. No rides just for pure pleasure, as yet, but definitely more inclination to go by bike for business.

Saturday, February 25, 2017

Powershell Transcript cmdlets and secondary runspaces gotcha

So, I had some fun this past week, with a piece of code that, stripped to its essentials, looked like

which yields

Stop-Transcript : An error occurred stopping transcription: The host is not currently transcribing.
At line:1 char:1
+ Stop-Transcript
+ ~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Stop-Transcript], PSInvalidOperationException
    + FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.StopTranscriptCommand

with a transcript (again, stripped to its essentials) of

Transcript started, output file is ...
PS>$pool = [System.Management.Automation.Runspaces.RunspaceFactory]::CreateRunspacePool(1,1)
PS># do stuff...
Windows PowerShell transcript end

with nothing after the Close() showing up.

It turns out that, however you create a runspace, even if using an instance of a custom PSHost subclass and explicitly minting one through CreateRunspace(), the runspace will still get attached to an internal PSHost subtype, which couples it to a whole web of other internal and/or sealed types, eventually linking it to the transcription state of the overall PowerShell session. And when a runspace closes, it closes all open transcripts attached to it.


Fortunately, there is one public API available to us that can sever this link, and one that makes a perverse sort of sense, after you've run through all the plumbing:

which finishes with

Transcript stopped, output file is...

and a transcript that looks like

Transcript started, output file is ...

PS>$pool = [System.Management.Automation.Runspaces.RunspaceFactory]::CreateRunspacePool(1,1)
PS>$save = [System.Management.Automation.Runspaces.Runspace]::DefaultRunspace
PS>try {
    [System.Management.Automation.Runspaces.Runspace]::DefaultRunspace = $null
    # do stuff...
    # do more stuff...
finally {
    [System.Management.Automation.Runspaces.Runspace]::DefaultRunspace = $save
Windows PowerShell transcript end

because it turns out that, via a long chain of indirections, it is the -- fortunately thread-static -- global default runspace which is the thing that contaminates our intended-to-be-isolated worker environment.

Now, it would be understandable if runspace construction were to directly use the default runspace as a prototype, but it's nothing so obvious. It actually comes in via the UI object that is tenuously attached to the runspace reaching out to the default runspace. That's not so good, and speaks of excessive internal coupling.

Checking metrics on the assembly System.Management.Automation, we can see that it is indeed highly internally coupled, with a relational cohesion of 7.22, which is a level that is not so much coherent as positively incestuous. So while I didn't spot any other obvious booby-traps waiting to be sprung, I'm sure there are others that will rise up and bite the occasional edge-case.

Sunday, February 05, 2017

SHA256.Create() and "Works on my machine" FIPS-compliance

I've just had an interesting run-in with a little-advertised and not backwards-compatible feature in .net 4.6 and up, and how it affects FIPS-compliance, for those of us who have to worry about such things.

You see, in the recent .net versions (unlike the older ones), the selection of the default implementation toggles on whether the machine has HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\FipsAlgorithmPolicy\[Enabled] set non-zero or not (or the equivalent group policy), and will select a FIPS-certified implementation for SHA256 (and SHA384 and SHA512), and, interestingly only for those flavours of SHA-2, using exactly the same criterion as is used to make the non-compliant implementations raise an exception on construction. So, assuming no app or machine level overrides, the matrix looks like this:

no FIPS enforcementFIPS enforced
.net 4.6 and up

(Dev machine)


"Works on my machine."
.net 4.5.2 or earlier

(Slow-moving customer environment)



The end-stop selection of algorithm defaults (where not overridden by a specific [class].Create()) in .net 4.5.2 are drawn from mscorlib alone, many FIPS-compliant, with the notable exceptions being the "new" (SHA-2, or AES which is present only by the original name of Rijndael), or old-and-deprecated (like MD5) algorithms. As in most cases, [DerivedClass].Create() is just a synonym for [BaseAlgorithm].Create(), you can get a false sense of security here -- SHA256CryptoServiceProvider.Create() will equally spit out an instance of SHA256Managed in three of the cases above, and SHA256Cng in the fourth ("works on my machine").

TL;DR -- if you have to worry about FIPS, don't use [Algorithm].Create(), but select the one you mean by calling its constructor explicitly.

Wednesday, February 01, 2017

January Cycling

Up to 14477.7, 0, 127.9 -- 108.7 + 0 + 1.8 = 109.5 miles in a chilly month, with a lot of days where I might have cycled blocked out by other things, so I only ended up commuting once a week, with one shopping trip and one expedition for fresh air on the New Year Bank Holiday. That may be well less than I did last year, but this time I'm not feeling ground down by the cycle-work-cycle-work-cook-eat-sleep routine I was caught in back then.

Sunday, January 22, 2017

Yet another thread 'main' panicked Rust gotcha -- mind your

Picking up the little Rust project I'd set aside in late summer, with the latest release, I got

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error { repr: Os { code: 2, message: "The system
 cannot find the file specified." } }', ../src/libcore\

Setting environment variable RUST_BACKTRACE to 1, and retrying gave

stack backtrace:
   0:   0xf314b7 - std::panicking::default_hook
                at C:\bot\slave\stable-dist-rustc-win-msvc-32\build\src\libstd\
   1:   0xf31caa - std::panicking::rust_panic_with_hook
                at C:\bot\slave\stable-dist-rustc-win-msvc-32\build\src\libstd\
   2:   0xf31b47 - std::panicking::begin_panic<collections::string::String>
                at C:\bot\slave\stable-dist-rustc-win-msvc-32\build\src\libstd\
   3:   0xf31a86 - std::panicking::begin_panic_fmt
                at C:\bot\slave\stable-dist-rustc-win-msvc-32\build\src\libstd\
   4:   0xf319e2 - std::panicking::rust_begin_panic
                at C:\bot\slave\stable-dist-rustc-win-msvc-32\build\src\libstd\
   5:   0xf36f82 - core::panicking::panic_fmt
                at C:\bot\slave\stable-dist-rustc-win-msvc-32\build\src\libcore\
   6:   0xf22402 - core::result::unwrap_failed<std::io::error::Error>
                at C:\bot\slave\stable-dist-rustc-win-msvc-32\build\src\libcore\
   7:   0xf21d0f - core::result::Result<std::process::ExitStatus, std::io::error::Error>::unwrap<std::process::ExitStatu
                at C:\bot\slave\stable-dist-rustc-win-msvc-32\build\src\libcore\
   8:   0xf23b5e - build_script_build::main
                at c:\Users\steve\hg\Projects\rust\HelloWorld\
   9:   0xf3556b - panic_unwind::__rust_maybe_catch_panic
                at C:\bot\slave\stable-dist-rustc-win-msvc-32\build\src\libpanic_unwind\
  10:   0xf322f0 - std::rt::lang_start
                at C:\bot\slave\stable-dist-rustc-win-msvc-32\build\src\libstd\
  11:   0xf23d01 - main
  12:   0xf39768 - __scrt_common_main_seh
                at f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl:253
  13: 0x75168e93 - BaseThreadInitThunk
  14: 0x772d9bc2 - RtlDestroyQueryDebugBuffer

which wasn't particularly helpful.

Resolution was an inspired guess -- my contained a path which ran a command by explicit path into the windows SDK for an x64 machine, when I was trying on an old 32-bit box.

Fixing the path to be selected according to whether the file actually exists resolved the issue.

Thursday, January 19, 2017

…and good riddance!

I took this screen-shot in mid-October 2007, well before the primary season that propelled the junior Senator from Illinois onto the national stage--

Today, I have a use for it, at last!

Wednesday, January 04, 2017

C# under the covers III

So, you have some code that looks like this

    private static bool Match(int item, int? target)
        if (target.HasValue)
            return item == target;

        return false;

How many tests do you need to write to get 100% branch coverage?

If you answered "two -- one with a value, one without", you'd be as surprised as I was when I tried it.

It turns out that the implicit extraction of the value of the nullable value contains its own HasValue check, and the IL looks like

IL_0000: nop
IL_0001: ldarga.s target
IL_0003: call instance bool valuetype [mscorlib]System.Nullable\u00601::get_HasValue()
IL_0008: ldc.i4.0
IL_0009: ceq
IL_000b: stloc.1
IL_000c: ldloc.1
IL_000d: brtrue.s IL_002b

IL_000f: nop
IL_0010: ldarg.0
IL_0011: stloc.2
IL_0012: ldarg.1
IL_0013: stloc.3
IL_0014: ldloc.2
IL_0015: ldloca.s CS$0$0003
IL_0017: call instance !0 valuetype [mscorlib]System.Nullable\u00601::GetValueOrDefault()
IL_001c: bne.un.s IL_0027

IL_001e: ldloca.s CS$0$0003
IL_0020: call instance bool valuetype [mscorlib]System.Nullable\u00601::get_HasValue()
IL_0025: br.s IL_0028

IL_0027: ldc.i4.0

IL_0028: stloc.0
IL_0029: br.s IL_002f

IL_002b: ldc.i4.0
IL_002c: stloc.0
IL_002d: br.s IL_002f

IL_002f: ldloc.0
IL_0030: ret

Roughly, it goes "get a value, or the default, and test that; if not equal, accept that, otherwise only accept the equality if the nullable had a value."

If you write

    private static bool Match(int item, int? target)
        if (target.HasValue)
            return item == target.Value;

        return false;

then there is no compiler-generated branch for you to be caught by -- and it's probably slightly better coding practise, anyway.