This action will delete this post on this instance and on all federated instances, and it cannot be undone. Are you certain you want to delete this post?
This action will delete this post on this instance and on all federated instances, and it cannot be undone. Are you certain you want to delete this post?
This action will block this actor and hide all of their past and future posts. Are you certain you want to block this actor?
This action will block this object. Are you certain you want to block this object?
Are you sure you want to delete the OAuth client [Client Name]? This action cannot be undone and will revoke all access tokens for this client.
Are you sure you want to revoke the OAuth token [Token ID]? This action cannot be undone and will immediately revoke access for this token.
#ktistec 178 hashtags

once you've seen one activitypub implementation, you've seen one activitypub implementation.
i just wrapped up a whole lot of interoperability work for ktistec. bottom line, you can't just read and implement the activitypub spec et al and expect anything to federate with your implementation. your best bet, in fact, is to doggedly copy the mastodon implementation, right down to the braces and brackets—since every other implementation is at least shooting for mastodon compatibility—and then work from there.
to be fair, about half of the fixes were arguably due to bugs in my own code. but seriously lemmy, why do you require the json-ld context to be a list, even when the context is defined by a single URL...?

one criticism of activitypub is that it's not a specification, and as a consequence you have to test extensively to ensure interoperability between implementations.
this is a valid criticism.
to some degree i guess i don't care. i'm building a free/open source application not a commercial product, and it's aimed at relatively tech-savvy users, and i kind of enjoy spelunking issues like these anyway, but for anyone whose goal is mass adoption of the "fediverse" concept, it's a problem.


commits a2f3fad to 485dbf2 add support for blocking actors and objects. like many things, blocking is built on the back on a lot of earlier cleanup and refactoring.
as expected, blocking an actor removes the actor and its content from your timelines. blocking an object removes only that object.
finishing this is the last blocker to a 1.0 release. 🎉

before it was called "agile programming" it was called "extreme programming". one of the tenets of extreme programming is "merciless refactoring". another is "edgy adjectives".
an often overlooked "freedom" in a free software project is the freedom to refactor, mercilessly. why turn a free software project into a feature factory? you can get that in an office job, right?
anyway, commits 14d22ca to 14fb9af do away with 1860 lines of code, while only adding 880 lines. more importantly, they do away with quite a lot of distracting boilerplate—like explicit identifiers (IRIs) that usually have no bearing on the outcome of a test.
the one big addition was spec_helper/factory.cr (349 lines), which adds lightweight factories that take care of the details of instantiating a valid model instance. i picked up the build/create paradigm from the factory_bot gem, and extended the let/let! pattern used in spectator.

in ktistec news, commits 4d2f699 through 4d2f699 include several improvements and bug fixes. highlights:
KTISTEC_DB environment variable overrides the default location for the SQLite database file. i use this during testing. it may be useful for some deployments.TaskWorker now kicks off as soon as a new task is scheduled. the previous implementation polled for new work every five seconds.loading="lazy".i'm also now only one feature away—blocking actors and objects—from tagging the 1.0.0 release.
† the race condition occurs when an activity, like a create, arrives that takes a long time to validate, maybe because ids need to be dereferenced. while it's being validated, an announce activity arrives for the same object. now two activities for the same object are being processed concurrently. being added to a timeline is a side-effect, and collecting all side-effects in one location made it easier to put the duplicate check after validation but before any side-effects, which saved me from having to unwind side-effects if a duplicate was detected.

what a difference one line of code makes!
commit fe18dc5 moved the line @saved_record : self | Nil = nil from the module Ktistec::Model::InstanceMethods into the macro Ktistec::Model.included.
that single change cut the build time in half and reduced the memory required to build by about a third. you can be sure the improvement came as a surprise!
but really, it wasn't just this change itself—although it introduced the biggest improvement—because after all of the subsequent refactoring, simply moving the line back didn't increase the build time again.
the build time also improved slightly after other subsequent commits. and several of those commits introduced changes that reduced the amount of macro generated code. and that's the key insight: macros reduce visible boilderplate but don't reduce actual code that needs to be compiled.
i'm still investigating, but clearly the original placement of the line resulted in the generation of a lot of redundant/unnecessary code!
TL;DR if you're planning on using macros in crystal, check your build times before and after your changes—i'm sure there's a corresponding commit somewhere in the past that introduced this problem and i didn't catch it!


building ktistec is still an endeavor—both in time and in space. i have work ahead of me to reduce the build footprint—since starting this project, i've learned that some combinations of the crystal language features i used to recreate rails magic (macros, named arguments and inheritance) are hard on the compiler.
in any case, having exceeded the capacity of the tiny linux vps that hosts epiktistes, i set out to build a statically linked executable on my laptop (macos mojave) that i could deploy to my vps (linux centos).
the official instructions, using docker and alpine linux, are here. to get it to build, i had to install the static libraries for sqlite, and to get it to run on my vps i had to specify the location of the openssl cert file, which is loaded at runtime and doesn't match the location in alpine linux.
tl;dr the steps
docker run --rm -it -v $(pwd):/workspace -w /workspace crystallang/crystal:latest-alpine shapk update && apk upgradeapk add sqlite-staticcrystal build src/ktistec/server.cr --staticexitSSL_CERT_FILE=/etc/ssl/certs/ca-bundle.crt ./server
commits 99a0fd6 to 70bcf3f implement metrics and charting.

an instance of the Point model records an occurrence of an event—for example, the arrival of an activity in my inbox. points have a timestamp and a value and can be aggregated by day, week, etc. aggregation takes into account the timezone of the account that's viewing the chart so you'll need to specify a timezone during setup or in your account settings. i use chart.js for the charts.
i'm only collecting inbox and outbox metrics right now, but this will expand to include other types of metrics—social events, errors, etc.
looking at the chart above... i clearly need to post more...