Run Flutter app on iOS 2021 edition

You need an apple developer account and XCode

Open the Flutter app in XCode

In Android Studio, go to Tools / Flutter / Open iOS module in XCode. I know, using ANDROID studio to make apps for an iPhone…

Prepare XCode

Connect your phone to the computer. On the top left part, click Runner > and select your phone. If you don’t see your device you’ll need to troubleshoot, don’t select “Any iOS device”

Go to XCode / Preferences / Account tab, press the plus button, select Apple ID and login to your Developer account. You’ll be prompted for keychain access, allow all. After you are done, make sure a team is available. Some tutorials made you do this step by manually creating a CSR key on your computer and upload it to Apple, following the wizard in XCode is much easier

Next, select runner on the left pane, and select signing & capabilities, make sure automatically manage signing is selected

Remotely debug your app

  • In XCode, select Windows / Device and simulators
  • Click on your phone, check the connect via network button

Wait until there’s a globe next to your phone’s name. That’s it, you can now disconnect your phone from the computer and deploy your app remotely to your phone by clicking the Run button

The run button

Automatically allow go binary in goland to listen on MacOS

Everytime you compile a go binary in goland and start it, MacOS will ask you to allow the binary to listen for incoming connection, which can quickly become a nuisance. To always allow the binary, do two things

Listen only on “localhost”

Set the execution environment to HOST=”localhost” for gin

Code sign the executable before launch

VoilĂ ! No more prompts!

Lessons building a JMeter/Caliper benchmarking system

Remote SSH access

  • While it seemed convenient at first, actually we can’t use remote access libraries like JSch http://www.jcraft.com/jsch/ or sshj https://github.com/hierynomus/sshj
    • These libraries re-implemented the ssh protocol and is based upon bouncy castle https://www.bouncycastle.org/
    • Bouncy castle, in turn requires a highly randomized source from the OS. But Amazon EC2 are virtual environment and thus have very little randomness
    • As a result, these libraries will hang for a long time, and may never complete
    • Solution: simply call the os’ natively installed ssh executable. It seems this has been modified to accomodate the environment and work much faster. This also reduced dependency on external libraries (don’t have to download jsch or sshj from maven)
    • Downside: while Jetmeter is written in java, dependency on ssh and scp means it can only run on MacOS or Linux

JMeter

  • While JMeter can be embedded as a library https://mvnrepository.com/artifact/org.apache.jmeter , this approach have the following downsides
    • You need to download external libraries
    • If you use JMeter plugins, you need to include those plugins as libraries, increasing the size of the build a lot
    • You’ll still need to include the JMeter binary and extension directory (yes, you need both build time and run time access)
    • This is due to historical reasons. JMeter has been developed a long time ago and they couldn’t break old conventions.
    • Including JMeter in our application will affect
      • Security. Any JMeter vulnerability will affect our application too
      • JMeter has a tendency to hang. Once we hand over control to the JMeter library it’s hard to take back, the only way is to fork a new process.
    • When we go with process forking, it’s hard to monitor the progress of JMeter (you need to constantly check for result files as JMeter provide no internal method for this)
    • JMeter was built to be mainly run from the command line. To do even basic operation like launching remote controller would require convoluted object instantiation and reflection to access JMeter’s internal types
    • Solution: Since we need to include JMeter library anyway, just call it as an external application and wait for it to finish

Caliper

  • When running Caliper via a remote session, caliper sometimes end the session during test (after around 5 seconds), but still running on the remote host
    • Can’t depend on caliper output
    • Can’t depend on the time caliper exit thread for control flow
    • Need to periodically pool caliper report file on remote host
    • Need to parse said file instead of console output

Migrating to Obsidian

Recently someone released Foam for VSCode on Obsidian, it led me down a rabbit hole of Second brain and Zettelkasten method. In short: it’s an enhanced mindmap with text, images and link between articles

Sound similar to a wiki? Yes. Shall I try out this new thing? Also yes.

So I started to Migrate all my notes to Obsidian, an excellent implementation of this idea (and it’s free for personal use).

My notes a scattered between SimpleNote, Google Keep and OneNote

Migrating from SimpleNote

You can export your notes to HTML from the web app. Then convert HTML to MD with pandoc

Migrating from Google Keep

You can use google Takeout to export your Keep notes to a bunch of HTML files, then use pandoc. You may need to edit the resulting md files a little bit. VS Code is an excellent tool for this

Migrating from OneNote

This is where most of my notes are, and is the most involved. You need

  • A Windows machine
  • OneNote Office Version (not the Windows Store version)

Use this script https://github.com/rab-bit/ConvertOneNote2MarkDown4Obsidian and follow the instruction. This is an updated version of the original script here with various bugs fixed.

TIL: Java stuff

Java Lambda as parameter

First you need an interface

    private interface Ec2Operation {
        void apply(Ec2Client ec2, String... instanceId);
    }

Then declare the operation (note that you don’t need to define “apply”, just use the interface name. “apply” can actually be anything, as you’ll call it later

Ec2Operation startInstance = (ec2, instances) -> {
StartInstancesRequest request = StartInstancesRequest.builder()
.instanceIds(instances)
.build();
ec2.startInstances(request);
};

Then use it with the interface as a signature, call the function you named

private RequestResult executeEc2Operation(Ec2Operation operation) {
    operation.apply(client, instances);
}

Then call the lambda as parameter in a third function

    public RequestResult start() {
        return executeEc2Operation(startInstance);
    }

Having to declare the interface explicitly makes it much more verbose than Javascript. However you get the benefit of a strong type.

Scala and Go’s approach is probably the best of both worlds: you just need to declare the type in the lambda itself.

SSH library for Java

JSCH is the first result in Google. However it hasn’t been updated in along time and doesn’t support newer algorithms.

SSHJ seems to be a more modern choice. It’s on github too!