Searching txt.sour.is

Twts matching #like
Sort by: Newest, Oldest, Most Relevant

@prologic@twtxt.net I have updated to kinda follow this. It now redirects to other webfingers if the resource has a different hostname. I’m still not sure what I should put multiple services with the same domain name. Like if they were to have conflicting properties.

⤋ Read More

@prologic@twtxt.net I have updated to kinda follow this. It now redirects to other webfingers if the resource has a different hostname. I’m still not sure what I should put multiple services with the same domain name. Like if they were to have conflicting properties.

⤋ Read More

Finally back! My VPS’s main drive got toasted. I got a freshly installed VPS now, got yarn set up and working now, now I have to fix the rest of the stuff.
I’ve been using apache for many many years, but I had so many issues getting it set up today, so I switched to nginx, and that took me like 2 minutes.. So yeah - I’ll use nginx from now on.

⤋ Read More
In-reply-to » Trying to wrap my head around webfinger..

so in effect it would look something like this:

---
subject: acct:me@sour.is
aliases:
  - salty:me@sour.is
  - yarn:xuu@ev.sour.is
  - status:xuu@chaos.social
  - mailto:me@sour.is
---
subject: salty:me@sour.is
aliases:
  - acct:me@sour.is
links:
  - rel:    self
    type:   application/json+salty
    href:   https://ev.sour.is/inbox/01GAEMKXYJ4857JQP1MJGD61Z5
    properties:
        "http://salty.im/ns/nick":    xuu
        "http://salty.im/ns/display": Jon Lundy
        "http://salty.im/ns/pubkey":     kex140fwaena9t0mrgnjeare5zuknmmvl0vc7agqy5yr938vusxfh9ys34vd2p
---
subject: yarn:xuu@ev.sour.is
links:
  - rel: https://txt.sour.is/user/xuu
    properties:
        "https://sour.is/rel/redirect": https://txt.sour.is/.well-known/webfinger?resource=acct%3Axuu%40txt.sour.is
---    
subject: status:xuu@chaos.social
links:
   - rel: http://joinmastodon.org#xuu%40chaos.social
     properties:
        "https://sour.is/rel/redirect": https://chaos.social/.well-known/webfinger?resource=acct%3Axuu%40chaos.social
---
subject: mailto:me@sour.is
...

⤋ Read More
In-reply-to » Trying to wrap my head around webfinger..

so in effect it would look something like this:

---
subject: acct:me@sour.is
aliases:
  - salty:me@sour.is
  - yarn:xuu@ev.sour.is
  - status:xuu@chaos.social
  - mailto:me@sour.is
---
subject: salty:me@sour.is
aliases:
  - acct:me@sour.is
links:
  - rel:    self
    type:   application/json+salty
    href:   https://ev.sour.is/inbox/01GAEMKXYJ4857JQP1MJGD61Z5
    properties:
        "http://salty.im/ns/nick":    xuu
        "http://salty.im/ns/display": Jon Lundy
        "http://salty.im/ns/pubkey":     kex140fwaena9t0mrgnjeare5zuknmmvl0vc7agqy5yr938vusxfh9ys34vd2p
---
subject: yarn:xuu@ev.sour.is
links:
  - rel: https://txt.sour.is/user/xuu
    properties:
        "https://sour.is/rel/redirect": https://txt.sour.is/.well-known/webfinger?resource=acct%3Axuu%40txt.sour.is
---    
subject: status:xuu@chaos.social
links:
   - rel: http://joinmastodon.org#xuu%40chaos.social
     properties:
        "https://sour.is/rel/redirect": https://chaos.social/.well-known/webfinger?resource=acct%3Axuu%40chaos.social
---
subject: mailto:me@sour.is
...

⤋ Read More
In-reply-to » Trying to wrap my head around webfinger..

@prologic@twtxt.net Unfortunately the RFC’s are a bit light in this regard. While it makes mention of different kinds of accounts like mailto: or status services.. it never combines them. It does make mention of using redirects to forward a request to other webfingers to provide additional detail.

I am kinda partial to using salty:acct:me@sour.is, yarn:acct:xuu@txt.sour.is, mailto:me@sour.is that could redirect to a specific service. and a parent account acct:me@sour.is that would reference them in some way. either in properties or aliases.

⤋ Read More
In-reply-to » Trying to wrap my head around webfinger..

@prologic@twtxt.net Unfortunately the RFC’s are a bit light in this regard. While it makes mention of different kinds of accounts like mailto: or status services.. it never combines them. It does make mention of using redirects to forward a request to other webfingers to provide additional detail.

I am kinda partial to using salty:acct:me@sour.is, yarn:acct:xuu@txt.sour.is, mailto:me@sour.is that could redirect to a specific service. and a parent account acct:me@sour.is that would reference them in some way. either in properties or aliases.

⤋ Read More

One of the frustrating parts of using twtxt for conversations is the URLs are, well… ugly. Anyone (like y’all yarn folks) looked at using webfinger for translating user@domain accounts to URLs?

⤋ Read More
In-reply-to » @prologic and @justamoment, this Gitxt project sounds really interesting. Can you tell us about some of your goals?

More specifically: Will this be expanded into something like Gitea with the concept of users and organizations, or will it stay with a simple flat repository model like upstream legit or cgit?

Also, the shorthand mention syntax has struck again. Apologies, @justamoment@twtxt.net.

⤋ Read More

it’s really funny when people tag jimmy wales on twitter when they don’t like some of the content on wikipedia. it’s like someone would tag Nat Friedman when they find a bug in a program hosted there

⤋ Read More
In-reply-to » Tutorial: Getting started with generics - The Go Programming Language -- Okay @xuu I quite like Go's generics now 🤣 After going through this myself I like the semantics and the syntax. I'm glad they did a lot of work on this to keep it simple to both understand and use (just like the rest of Go) 👌 Media #GoLang #Generics

@prologic@twtxt.net see where its used maybe that can help.
https://github.com/sour-is/ev/blob/main/app/peerfinder/http.go#L153

This is an upsert. So I pass a streamID which is like a globally unique id for the object. And then see how the type of the parameter in the function is used to infer the generic type. In the function it will create a new *Info and populate it from the datastore to pass to the function. The func will do its modifications and if it returns a nil error it will commit the changes.

The PA type contract ensures that the type fulfills the Aggregate interface and is a pointer to type at compile time.

⤋ Read More
In-reply-to » Tutorial: Getting started with generics - The Go Programming Language -- Okay @xuu I quite like Go's generics now 🤣 After going through this myself I like the semantics and the syntax. I'm glad they did a lot of work on this to keep it simple to both understand and use (just like the rest of Go) 👌 Media #GoLang #Generics

@prologic@twtxt.net see where its used maybe that can help.
https://github.com/sour-is/ev/blob/main/app/peerfinder/http.go#L153

This is an upsert. So I pass a streamID which is like a globally unique id for the object. And then see how the type of the parameter in the function is used to infer the generic type. In the function it will create a new *Info and populate it from the datastore to pass to the function. The func will do its modifications and if it returns a nil error it will commit the changes.

The PA type contract ensures that the type fulfills the Aggregate interface and is a pointer to type at compile time.

⤋ Read More

tbh whenever someone is like “the existing arguments for agi xrisk were insufficient/unclear, here’s my better version” the arguments read exactly the same to me as the existing ones.

⤋ Read More
In-reply-to » @prologic: Reduced refresh interval to 7200 seconds :-)

@prologic@twtxt.net I guess that refresh field could be easily replaced with Expires HTTP header (I realize that users on neocities.org cannot control this header, for example). And clients should also respect headers like Last-Modified/If-Modified-Since (304), you’re right about that. P.S. twtwt doens’t have a caching mechanism for now, but I plan to implement it in generic way using HTTP headers.

⤋ Read More
In-reply-to » @prologic (re: Just discovered ...) On the one hand, twtxt has become more popular thanks to Yarn.social. On the other hand, subject and hashtag extensions took away the simplicity of the protocol. For example, it is impossible to understand which conversation (#base32hash) a tweet refers to or to reply to a tweet without going to a yarn.social pod. Compare with re: in this tweet which can be written without using any client at all

@prologic@twtxt.net: I understand the benefits of using hashes, it’s much easier to implement client applications (at the expense of ease of use without the proper client). I must say that I like the way the metadata extension is done. Simple and elegant! It’s hard to design simple things!

⤋ Read More

I use Firefox as my preferred web browser both on PCs and my phone. One extension is always installed: uBlock Origin. The web is so much nicer with all the ads and tracking removed. But today I also retried an extension that will probably join the “must install” list: DarkReader. Especially when I’m browsing the web on my phone in the early morning, I don’t like to be blinded by white websites. Since March DarkReader has finally an option to detect if a website already has a dark theme and only apply it’s color chan … ⌘ Read more

⤋ Read More
In-reply-to » ahh this is useful https://go.dev/doc/modules/managing-dependencies. the go culture doesn't typically have large dependency graphs like Ruby or JS.

@lyse@lyse.isobeef.org im talking like some JS projects i have seen with 1-2G node_modules dirs. though yarn is quite vast in its modules because it does a LOOOOOOT of stuff in the background.

⤋ Read More
In-reply-to » ahh this is useful https://go.dev/doc/modules/managing-dependencies. the go culture doesn't typically have large dependency graphs like Ruby or JS.

@lyse@lyse.isobeef.org im talking like some JS projects i have seen with 1-2G node_modules dirs. though yarn is quite vast in its modules because it does a LOOOOOOT of stuff in the background.

⤋ Read More

Well, people should be able to talk, even if it’s the ‘wrong’ topic.
I think the whole ‘covid disinformation’ policy at twitter and others (spotify) is ridiculous.
A banner that pops up telling you to go ‘here’ for latest info is crazy.
People die from all kinds of things, covid is no exception from that, but no other virus has been put on display like this one. And also not even being able to discuss things around it (except for the cemented truth) is not something I like. I’m not a conspiracy theorist or anything like that - but I love discussing things, and when you cannot even do that - then I have a issue with it. So many people got banned for simply discussing or trying to discuss issues around it.

⤋ Read More
In-reply-to » git-bug

Ah git-bug! Ive chatted with the creator when he was working on the graphql parts. Its working with git objects directly sorta like how git-repo does code reviews. Its a pretty neat idea for storing data along side the branches. I believe they don’t add a disconnected branch to avoid data getting corrupted by merging branches or something like that.

⤋ Read More
In-reply-to » git-bug

Ah git-bug! Ive chatted with the creator when he was working on the graphql parts. Its working with git objects directly sorta like how git-repo does code reviews. Its a pretty neat idea for storing data along side the branches. I believe they don’t add a disconnected branch to avoid data getting corrupted by merging branches or something like that.

⤋ Read More
In-reply-to » Tried to pull down the latest yarn, but I get this: unable to access 'https://git.mills.io/yarnsocial/yarn/': server certificate verification failed. CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none

@prologic@twtxt.net Most likely, ancient debian on that webserver - I’ll assume the problem is on my end and see if I can get it sorted.

⤋ Read More

How to Build a Restreaming Server with a Raspberry Pi
First of all, what is a restreaming server? Sometimes you want to livestream video from a device like an ATEM Mini or OBS to multiple destinations. Many devices and software like this will let you push video to just one RTMP destination at a time. ⌘ Read more

⤋ Read More

Although there are definitely reasons to hate Windows, there are also reasons to like Windows 11: Linux GUI apps, Android apps, winget package manager and improved window tiling. It would be even better, when one wouldn’t need to toogle all the privacy and telemety settings first… ⌘ Read more

⤋ Read More
In-reply-to » Atom vs. RSS: https://mckinley.cc/blog/20221109.html

@mckinley@twtxt.net Thank you! I didn’t even know about signing and encrypting XML documents. Right, RSS is a little bit messy.

Unfortunately, the autodiscovery document in one of your linked resources does not exist anymore. What annoys me in Atom is the distinction between <id> and <link>. I always want my URL also to be my ID, so I have to duplicate that – unnecessarily in my opinion.

Also, never found a good explanation why I should add <link rel="self" … /> to my feeds. I just do, but I don’t understand why. The W3C Feed Validation Service says:

[…] This value is important in a number of subscription scenarios where often times the feed aggregator only has access to the content of the feed and not the location from which the feed was fetched.

This just sounds like a very questionable bandaid to bad software architecture. Why would the feed parser need access to the feed URL at this stage? And if so, why not just pass down the input source? Just doesn’t make sense to me.

Also, I just noticed that I reference the http://purl.org/rss/1.0/modules/syndication/ namespace, but don’t use it in most of my feeds. Gotta fix that. Must have copied that from my yfav feed without paying attention what I’m doing.

Your article made me reread the Atom spec and I found out, that I can omit the <author> in the <entry> when I specify a global <author> at <feed> level. Awesome! Will do that as well and thus reduce the feed size.

⤋ Read More
In-reply-to » Trying to figure out what sql query maddy does to change user passwords, but first, i'm looking for the subcommand that actually does that... on the source code

it uses the queries you define for add/del/set/keys. which corrispond to something like INSERT INTO <table> (key, value) VALUES ($key, $value), DELETE ..., or UPDATE ...

the commands are issued by using the maddycli but not the running maddy daemon.

see https://maddy.email/reference/table/sql_query/

the best way to locate in source is anything that implements the MutableTable interface… https://github.com/foxcpp/maddy/blob/master/framework/module/table.go#L38

⤋ Read More
In-reply-to » Trying to figure out what sql query maddy does to change user passwords, but first, i'm looking for the subcommand that actually does that... on the source code

it uses the queries you define for add/del/set/keys. which corrispond to something like INSERT INTO <table> (key, value) VALUES ($key, $value), DELETE ..., or UPDATE ...

the commands are issued by using the maddycli but not the running maddy daemon.

see https://maddy.email/reference/table/sql_query/

the best way to locate in source is anything that implements the MutableTable interface… https://github.com/foxcpp/maddy/blob/master/framework/module/table.go#L38

⤋ Read More

I was inclined to let this go so as not to stir anything up, but after some additional thought I’ve decided to call it out. This twt:

Image

is exactly the kind of ad hominem garbage I came to expect from Twitter™, and I’m disappointed to see it replicated here. Rummaging through someone’s background trying to find a “gotcha” argument to take credibility away from what a person is saying, instead of engaging the ideas directly, is what trolls and bad faith actors do. That’s what the twt above does (falsely, I might add–what’s being claimed is untrue).

If you take issue with something I’ve said, you can mute me, unfollow me, ignore me, use TamperMonkey to turn all my twts into gibberish, engage the ideas directly, etc etc etc. There are plenty of options to make what I said go away. Reading through my links, reading about my organization’s CEO’s background, and trying to use that against me somehow (after misinterpreting it no less)? Besides being unacceptable in a rational discussion, and besides being completely ineffective in stopping me from expressing whatever it is you didn’t like, it’s creepy. Don’t do that.

⤋ Read More

How to Fix and Debug Docker Containers Like a Superhero
While containers help developers rapidly build and run cross-platform applications, creating error-free apps remains a constant challenge. And while it’s not always obvious how container errors occur, this mystery is even harder for newer developers to unravel. Figuring out how to debug Docker containers can seem daunting. In this Community All-Hands session, Ákos Takács demonstrated how […] ⌘ Read more

⤋ Read More

After all, debugging is still fun!
One reason I use an Android smartphone is that there are apps like Indigenous (a MicroPub-compatible app for posting from your phone to a MicroPub-compatible blog). And even if the app ever disappears from the store, there’s still the option to manually install the app. And if you need to, you can also develop your own apps without having to invest nearly $100 a year. ⌘ Read more

⤋ Read More
In-reply-to » @prologic Libera's insistence on giving them an e-mail and my real IP address makes me really not want to give them either one. Otherwise, I'd probably talk in IRC regularly.

for service registration like nickserv. really its only for password recovery so a trow away is fine.

⤋ Read More
In-reply-to » @prologic Libera's insistence on giving them an e-mail and my real IP address makes me really not want to give them either one. Otherwise, I'd probably talk in IRC regularly.

for service registration like nickserv. really its only for password recovery so a trow away is fine.

⤋ Read More

Why we signed the Copenhagen Pledge on Tech for Democracy
As the home for developers, we understand the key role our communities play in steering digital transformation and maintaining societal infrastructure. That’s why we choose to drive and support policies and initiatives like the Copenhagen Pledge on Tech for Democracy. We’re committed to working with like-minded organizations, governments, and civil society to make digital technologies work for democracy and human rights, … ⌘ Read more

⤋ Read More

GoToSocial seems like a promising alternative to Mastodon. It’s written in Go (👍 in my opinion), lightweight and pretty good documented so far. It’s still “alpha software” but seems to make great progress. In the past, I self hosted a microblog.pub instance and then after some time without any Fediverse profile other than my blog, which has ActivityPub support as well, signed up at Fosstodon to be able to reply to blog comments from the Fediverse. I already set up an instace of GTS, but will probably wait to use it … ⌘ Read more

⤋ Read More

@ocdtrekkie@twtxt.net That is cool that there is no tpic. Its not like people on these open platforms have to use linux or some free and open os. Anyone can use whatever they want to. Yarn is just a web ui for twtxt and the os does not matter. I can’t say on for long time at midnight and I left before you started.

⤋ Read More

@prologic@twtxt.net I think those are fine because its just sharing someone elses post to people who follow you. Those people who follow you might not follow the orginal person and in return might never see that post unless its retoos/retweets. The thing that is harmful is likes.

⤋ Read More

@prologic@twtxt.net Yeah I am not one of these people who just have a twtxt file and end up posting a few things but not interacting with anyone. I do want to interact with the people of twtxt and yarn users. And not just twtxt users but I do care somewhat about the yarn users because really yarn is twtxt but with additions to make the experience better and a webui and the such like multi users. On top of that yarn and the twtxt clients add things like threads that are even helpful for twtxt users.

⤋ Read More

The thing is I don’t know how to search the web logs on Codeberg or even if they are public. That is the issue with just regular text files. The thing with having the follower list in the twtxt file is that then it knows to track friends of friends like with yarn.
If not having www is an issue when I will add it in. Good to know its something I have to change

⤋ Read More

@movq@uninformativ.de Do you know how I would find people that reply to my posts or replies or even mention my users? Prologic tried to contact me and unless I found him on the yarn pod then I would not know he exists and wants to talk to me. The user agents would work but I don’t know if I can view my web server logs from codeberg pages and I don’t know how to monitor my logs for mentions. What about the way yarn does it by added people you follow to your twtxt file and having friends of friends like yarn does it be a thing for jenny. Just an idea

⤋ Read More
In-reply-to » @prologic I do think the post about how to setup jenny + mutt over on the uninformativ.de blog is still a great post. I used that post to see the steps to set it up and it works fine. Though I can write some blog post with some more documentation for things like auto publishing. The big issue with plain twtxt is that I would have not seen your post unless I looked on twtxt.net when I was looking at yarn a little bit more. Twtxt does overcome the issue by introducing the registry but I can't figure out any way to use them for Jenny and almost no one uses them in the first place. So I can't see anyones replies or mentions unless I am following them. Yarn does overcome the issue by friends of friends as you would know as the creator of yarn.

@prologic@twtxt.net That is why yarn is better then something like activity pub. Everything over on activity pub tries to work with Mastodon not because its better but because its the most popular. Twtxt clients on the other hand tries to work with the yarn additions because most of the additions improve things even for twtxt users.

⤋ Read More
In-reply-to » got jenny setup and threads works completly fine but now I want to figure out how to get auto publishing working

@prologic@twtxt.net I never tried out any of the other clients except jenny with mutt. The best thing about yarn vs something like Mastodon is that its more promoted of the specification of twtxt files instead of server part. Twtxt can be hosted on some free static site host or some git server even so its really low resouces. Just a basic text file. As far as I know yarn is mostly just a web ui around twtxt and an extnetion to the specification to add some more usability and modern things. Anyone can join decentrilized network by having a twtxt file somewhere. If you want to support the specification of twtxt then that is really something most projects don’t do and they promote the server software mostly.

⤋ Read More
In-reply-to » @prologic I do think the post about how to setup jenny + mutt over on the uninformativ.de blog is still a great post. I used that post to see the steps to set it up and it works fine. Though I can write some blog post with some more documentation for things like auto publishing. The big issue with plain twtxt is that I would have not seen your post unless I looked on twtxt.net when I was looking at yarn a little bit more. Twtxt does overcome the issue by introducing the registry but I can't figure out any way to use them for Jenny and almost no one uses them in the first place. So I can't see anyones replies or mentions unless I am following them. Yarn does overcome the issue by friends of friends as you would know as the creator of yarn.

@prologic@twtxt.net Yeah I don’t even know how to use them once I added myself to the registries. The jarn search engine is similar to the registries thing but its easier to search and find things from. Also I assume its easier to use it in the yarn pods and whatever elese to get new posts. I would always like to see yarn work with regular twtxt because there is advantges to plain twtxt.

⤋ Read More
In-reply-to » got jenny setup and threads works completly fine but now I want to figure out how to get auto publishing working

@prologic@twtxt.net I do think the post about how to setup jenny + mutt over on the uninformativ.de blog is still a great post. I used that post to see the steps to set it up and it works fine. Though I can write some blog post with some more documentation for things like auto publishing. The big issue with plain twtxt is that I would have not seen your post unless I looked on twtxt.net when I was looking at yarn a little bit more. Twtxt does overcome the issue by introducing the registry but I can’t figure out any way to use them for Jenny and almost no one uses them in the first place. So I can’t see anyones replies or mentions unless I am following them. Yarn does overcome the issue by friends of friends as you would know as the creator of yarn.

⤋ Read More
In-reply-to » Today I found that Solarpunk is a thing: https://www.wikiwand.com/en/Solarpunk

@abucci@anthony.buc.ci Its not better than a Cat5e. I have had two versions of the device. The old ones were only 200Mbps i didn’t have the MAC issue but its like using an old 10baseT. The newer model can support 1Gbps on each port for a total bandwidth of 2Gbps.. i typically would see 400-500Mbps from my Wifi6 router. I am not sure if it was some type of internal timeout or being confused by switching between different wifi access points and seeing the mac on different sides.

Right now I have my wifi connected directly with a cat6e this gets me just under my providers 1.3G downlink. the only thing faster is plugging in directly.

MoCA is a good option, they have 2.5G models in the same price range as the 1G Powerline models BUT, only if you have the coax in wall already.. which puts you in the same spot if you don’t. You are for sure going to have an outlet in every room of the house by code.

⤋ Read More
In-reply-to » Today I found that Solarpunk is a thing: https://www.wikiwand.com/en/Solarpunk

@abucci@anthony.buc.ci Its not better than a Cat5e. I have had two versions of the device. The old ones were only 200Mbps i didn’t have the MAC issue but its like using an old 10baseT. The newer model can support 1Gbps on each port for a total bandwidth of 2Gbps.. i typically would see 400-500Mbps from my Wifi6 router. I am not sure if it was some type of internal timeout or being confused by switching between different wifi access points and seeing the mac on different sides.

Right now I have my wifi connected directly with a cat6e this gets me just under my providers 1.3G downlink. the only thing faster is plugging in directly.

MoCA is a good option, they have 2.5G models in the same price range as the 1G Powerline models BUT, only if you have the coax in wall already.. which puts you in the same spot if you don’t. You are for sure going to have an outlet in every room of the house by code.

⤋ Read More
In-reply-to » Does anyone of you use PGP encrypted mail, or any kind or email encryption? Why? Why not?

I maintain keys for my email addresses.. but like most in this thread i almost never receive encrypted emails.. other than the BTC exchange i use that sends automated mail encrypted.

⤋ Read More
In-reply-to » Does anyone of you use PGP encrypted mail, or any kind or email encryption? Why? Why not?

I maintain keys for my email addresses.. but like most in this thread i almost never receive encrypted emails.. other than the BTC exchange i use that sends automated mail encrypted.

⤋ Read More
In-reply-to » Hi, I am playing with making an event sourcing database. Its super alpha but I thought I would share since others are talking about databases and such.

Progress! so i have moved into working on aggregates. Which are a grouping of events that replayed on an object set the current state of the object. I came up with this little bit of generic wonder.

type PA[T any] interface {
	event.Aggregate
	*T
}

// Create uses fn to create a new aggregate and store in db.
func Create[A any, T PA[A]](ctx context.Context, es *EventStore, streamID string, fn func(context.Context, T) error) (agg T, err error) {
	ctx, span := logz.Span(ctx)
	defer span.End()

	agg = new(A)
	agg.SetStreamID(streamID)

	if err = es.Load(ctx, agg); err != nil {
		return
	}

	if err = event.NotExists(agg); err != nil {
		return
	}

	if err = fn(ctx, agg); err != nil {
		return
	}

	var i uint64
	if i, err = es.Save(ctx, agg); err != nil {
		return
	}

	span.AddEvent(fmt.Sprint("wrote events = ", i))

	return
}

fig. 1

This lets me do something like this:

a, err := es.Create(ctx, r.es, streamID, func(ctx context.Context, agg *domain.SaltyUser) error {
		return agg.OnUserRegister(nick, key)
})

fig. 2

I can tell the function the type being modified and returned using the function argument that is passed in. pretty cray cray.

⤋ Read More
In-reply-to » Hi, I am playing with making an event sourcing database. Its super alpha but I thought I would share since others are talking about databases and such.

Progress! so i have moved into working on aggregates. Which are a grouping of events that replayed on an object set the current state of the object. I came up with this little bit of generic wonder.

type PA[T any] interface {
	event.Aggregate
	*T
}

// Create uses fn to create a new aggregate and store in db.
func Create[A any, T PA[A]](ctx context.Context, es *EventStore, streamID string, fn func(context.Context, T) error) (agg T, err error) {
	ctx, span := logz.Span(ctx)
	defer span.End()

	agg = new(A)
	agg.SetStreamID(streamID)

	if err = es.Load(ctx, agg); err != nil {
		return
	}

	if err = event.NotExists(agg); err != nil {
		return
	}

	if err = fn(ctx, agg); err != nil {
		return
	}

	var i uint64
	if i, err = es.Save(ctx, agg); err != nil {
		return
	}

	span.AddEvent(fmt.Sprint("wrote events = ", i))

	return
}

fig. 1

This lets me do something like this:

a, err := es.Create(ctx, r.es, streamID, func(ctx context.Context, agg *domain.SaltyUser) error {
		return agg.OnUserRegister(nick, key)
})

fig. 2

I can tell the function the type being modified and returned using the function argument that is passed in. pretty cray cray.

⤋ Read More
In-reply-to » I did a take home software engineering test for a company recently, unfortunately I was really sick (have finally recovered) at the time 😢 I was also at the same time interviewing for an SRE position (as well as Software Engineering).

@prologic@twtxt.net Error handling especially in Go is very tricky I think. Even though the idea is simple, it’s fairly hard to actually implement and use in a meaningful way in my opinion. All this error wrapping or the lack of it and checking whether some specific error occurred is a mess. errors.As(…) just doesn’t feel natural. errors.Is(…) only just. I mainly avoided it. Yesterday evening I actually researched a bit about that and found this article on errors with Go 1.13. It shed a little bit of light, but I still have a long way to go, I reckon.

We tried several things but haven’t found the holy grail. Currently, we have a mix of different styles, but nothing feels really right. And having plenty of different approaches also doesn’t help, that’s right. I agree, error messages often end up getting wrapped way too much with useless information. We haven’t found a solution yet. We just noticed that it kind of depends on the exact circumstances, sometimes the caller should add more information, sometimes it’s better if the callee already includes what it was supposed to do.

To experiment and get a feel for yesterday’s research results I tried myself on the combined log parser and how to signal three different errors. I’m not happy with it. Any feedback is highly appreciated. The idea is to let the caller check (not implemented yet) whether a specific error occurred. That means I have to define some dedicated errors upfront (ErrInvalidFormat, ErrInvalidStatusCode, ErrInvalidSentBytes) that can be used in the err == ErrInvalidFormat or probably more correct errors.Is(err, ErrInvalidFormat) check at the caller.

All three errors define separate error categories and are created using errors.New(…). But for the invalid status code and invalid sent bytes cases I want to include more detail, the actual invalid number that is. Since these errors are already predefined, I cannot add this dynamic information to them. So I would need to wrap them à la fmt.Errorf("invalid sent bytes '%s': %w", sentBytes, ErrInvalidSentBytes"). Yet, the ErrInvalidSentBytes is wrapped and can be asserted later on using errors.Is(err, ErrInvalidSentBytes), but the big problem is that the message is repeated. I don’t want that!

Having a Python and Java background, exception hierarchies are a well understood concept I’m trying to use here. While typing this long message it occurs to me that this is probably the issue here. Anyways, I thought, I just create a ParseError type, that can hold a custom message and some causing error (one of the three ErrInvalid* above). The custom message is then returned at Error() and the wrapped cause will be matched in Is(…). I then just return a ParseError{fmt.Sprintf("invalid sent bytes '%s'", sentBytes), ErrInvalidSentBytes}, but that looks super weird.

I probably need to scrap the “parent error” ParseError and make all three “suberrors” three dedicated error types implementing Error() string methods where I create a useful error messages. Then the caller probably could just errors.Is(err, InvalidSentBytesError{}). But creating an instance of the InvalidSentBytesError type only to check for such an error category just does feel wrong to me. However, it might be the way to do this. I don’t know. To be tried. Opinions, anyone? Implementing a whole new type is some effort, that I want to avoid.

Alternatively just one ParseError containing an error kind enumeration for InvalidFormat and friends could be used. Also seen that pattern before. But that would then require the much more verbose var parseError ParseError; if errors.As(err, &parseError) && parseError.Kind == InvalidSentBytes { … } or something like that. Far from elegant in my eyes.

⤋ Read More
In-reply-to » Hi, I am playing with making an event sourcing database. Its super alpha but I thought I would share since others are talking about databases and such.

I have updated my eventDB to have subscriptions! It now has websockets like msgbus. I have also added a in memory store that can be used along side the disk backed wal.

⤋ Read More