Month: May 2021

Bees!

We got our nucs installed into their new homes — we were worried that there wouldn’t be any bees in the one hive because it was so quiet. But both nucs were full of bees doing all sorts of bee things.

In one of the colonies, we found a marked queen.

Chainsaw spline sizes

There are a few things about chainsaws that we’re learning as Scott is working on both this cheap knock-off chainsaw we got from Amazon and an old (very solid) chainsaw his dad brought over. Today’s lesson was spline size — there’s mini, small, and standard. But what’s small mean?

Mini spline – 17mm
Small spline – 19mm
Standard spline – 22mm

Turns out we weren’t wrong — we’d ordered a small spline rim sprocket, and it didn’t fit on our chainsaw because they sent us a standard spline sprocket — 22mm ID instead of 19mm ID. But now I know why we ordered exactly what we needed.

Adventure Turkeys

We picked up four friends for TurkeyGuy on Sunday. I wasn’t going to chance shipping again. We considered getting some of the franken-turk broad-breast things from Meyers down in Polk — I really don’t want to create demand for animals that grow so quickly their bodies give out. And a big draw to raising our own animals is that the animals make more all on their own. Luckily, I found someone about an hour away from here that’s really into breed preservation (and heirloom vegetables too!). So we went on a second adventure over the weekend and picked up four more Spanish Black turkeys. We had a great time meeting the folks at Ohio Heritage Poultry — and got to see all sorts of heritage turkeys. One of the coolest things is that they’ve got a Spanish tom that will sit on the nest — both turkey parents take turns keeping the eggs safe and warm, so each one gets a chance to run around, eat, drink … I’m hoping this is an instinctual thing that carries on with our turkeys because that seems so much healthier than a single bird isolating herself and barely budging from the nest.

Anya fed and watered our new poults before we headed home. The new guys are a little older than TurkeyGuy — we put the new guys into the brooder and they were instant friends. TurkeyGuy wants to be big like them — he stands with the largest poult and stretches his neck out so they’re the same height. Today, Anya set the baby tractor in a shady spot outside and took all of the poults on their first outdoor adventure. They’re such chill critters — they wandered around, pecked at clover, scratched around in the dirt, and napped. It’s going to be colder for the next week … but they’ll be happy to get outside again next week.

On UUIDs

RFC 4122 UUID Versions:

1 — Datetime and MAC based
48-bit MAC address, 60-bit timestamp, 13-14 bit uniquifying sequence

2 — Datetime and MAC based with DCE security
8 least significant clock sequence numbers and least significant 32 bits of timestamp. RFC doesn’t reallly provide details on DCE security

3 — Hashed Namespace
MD5 hash of namespace

4 — Random
6 pre-determined bits (4 bits for version, 2-3 bits for variant 1 or 2) and 122 bits for 2^122 possible v4 variant 1 UUIDs

5 — Hashed Namespace
SHA-1 hash of namespace

In my case, I hesitate to use a v1 or v2 UUID because I have scripts executing in cron on the same host. The probability of the function being called at the same microsecond time seems higher than the pseudo-random number generator popping the same value in the handful of hours for which the UUIDs will be persisted for deduplication.

v3 or v5 UUIDs are my fallback position if we’re seeing dups in v4 — the namespace would need to glom together the script name and microsecond time to make a unique string when multiple scripts are running the function concurrently.

Magic Bees

One of our chickens, Soaring Eagle, manages to escape the chicken tractor rather frequently. Even when I’ve locked it down — Anya doesn’t get the door closed up well, and I know exactly how they escape … but I’ve got that thing locked down. And, still, there’s a chicken in the yard. Because she’s a magic chicken.

We drove out to pick up our bees on Saturday. Scott was apprehensive about them because, well, it’s a big box full of bees. The guy was in the middle of explaining how the box is all sealed up and maybe a bee or two might escape, but they’d buzz around the back window as we drove and it’d all be fine. Except we started noticing a stream of bees coming out of the nuc. We, it seems, have magic bees too. The bee guy put bags around our nucs so we wouldn’t have a hundred bees buzzing around the car as we drove. That turned out to be a really good thing. The one nuc had a handful of bees in the bag. The one we’d noticed the bees coming out of? It most certainly did have a couple hundred bees outside of the box. I carried this box to the back of our property. Getting the bag off was a bit of a challenge even in a bee suit. They weren’t super thrilled about the relocation process. But they’re happily settled now.

Kafka Troubleshooting (for those who enjoy reading network traces)

I finally had a revelation that allowed me to definitively prove that I am not doing anything strange that is causing duplicated messages to appear in the Kafka stream — it’s a clear text protocol! That means you can use Wireshark, tcpdump, etc to capture everything that goes over the wire. This shows that the GUID I generated for the duplicated message only appears one time in the network trace. Whatever funky stuff is going on that makes the client see it twice? Not me 😊

I used tcpdump because the batch server doesn’t have tshark (and it’s not my server, so I’m not going to go requesting additional binaries if there’s something sufficient for my need already available). Ran tcpdump -w /srv/data/ljr.cap port 9092 to grab everything that transits port 9092 while my script executed. Once the batch completed, I stopped tcpdump and transferred the file over to my workstation to view the capture in Wireshark. Searched the packet bytes for my duplicated GUID … and there’s only one.

Confluent Kafka Queue Length

The documentation for the Python Confluent Kafka module includes a len function on the producer. I wanted to use the function because we’re getting a number of duplicated messages on the client, and I was trying to isolate what might be causing the problem. Unfortunately, calling producer.len() failed indicating there’s no len() method. I used dir(producer) to show that, no, there isn’t a len() method.

I realized today that the documentation is telling me that I can call the built-in len() function on a producer to get the queue length.

Code:

print(f"Before produce there are {len(producer)} messages awaiting delivery")
producer.produce(topic, key=bytes(str(int(cs.timestamp) ), 'utf8'), value=cs.SerializeToString() )
print(f"After produce there are {len(producer)} messages awaiting delivery")
producer.poll(0) # Per https://github.com/confluentinc/confluent-kafka-python/issues/16 for queue full error
print(f"After poll0 there are {len(producer)} messages awaiting delivery")

Output:

Before produce there are 160 messages awaiting delivery
After produce there are 161 messages awaiting delivery
After poll0 there are 155 messages awaiting delivery

Boolean Opts in Python

I have a few command line arguments on a Python script that are most readily used if they are boolean. I sometimes need a “verbose” option for script debugging — print a lot of extra stuff to show what’s going on, and I usually want a “dry run” option where the script reads data, performs calculations, and prints results to the screen without making any changes or sending data anywhere (database, email, etc). To use command line arguments as boolean values, I use a function that converts a variety of possible inputs to True/False.

def string2boolean(strInput):
    """
    :param strInput: String string to be converted to boolean
    :return: Boolean representation of input
    """
    if isinstance(strInput, bool):
        return strInput
    if strInput.lower() in ('yes', 'true', 't', 'y', '1'):
        return True
    elif strInput.lower() in ('no', 'false', 'f', 'n', '0'):
        return False
    else:
        raise argparse.ArgumentTypeError('Boolean value expected.')

Use “type” when adding the argument to run the input through your function.

    parser.add_argument('-r', '--dryrun', action='store', type=string2boolean, dest='boolDryRun', default=False, help="Preview data processing without sending data to DB or Kafka. Valid values: 'true' or 'false'.")

Feeding Baby Turkeys

I figured out a good way to feed somewhat spry turkey poults — the really weak ones, we used a q-tip or pipette to feed … but the one that is walking around and doing turkey things. Well, some turkey things but not the ‘eating’ and ‘drinking’? I mixed the baby turkey chow (turkey & game bird starter) with some of the electrolyte water to make a mush. Then I put a little bit of the mush on my finger-tip. Spry baby turkeys love to peck at your fingertip. You can move your finger toward the bowl of mush, lower it into the mush, and get them to eat from the bowl. Even if they just eat the mush from your fingertip — they’re getting food and liquid.

Anya found another way to lure the turkey to its food — basically the cat / laser pointer game. We have a laser temperature gun, and she pointed the light onto the floor of the brooder. And moved the light as the little guy chased after it. When the light settles into the food or water, they’ll peck at it. You have to be careful not to get the laser light into its eye!