How to Set Up Your Local Node.js Development Environment Using Docker
Learn how to set up a local Node.js development environment using Docker with this step-by-step guide! ⌘ Read more
@jason@jasonsanta.xyz Hey Jason! Welcome to the twtxtverse!
@jason@jasonsanta.xyz Hey Jason! Welcome to the twtxtverse!
Git’s database internals II: commit history queries
This post explores Git commit history as a database where ‘git log’ is the query language. Learn about Git’s custom query index – the commit-graph file – and how to make sure it’s enabled in your repositories. ⌘ Read more
@mckinley@twtxt.net really the language authors should have added those to the standard spec by now. That is just obscene.
@mckinley@twtxt.net really the language authors should have added those to the standard spec by now. That is just obscene.
JMP: Signup with Cheogram Android
Welcome to JMP.chat! If you are looking for a simple guide on how to sign up for JMP, then you have come to the right place! We will be keeping this guide up-to-date if there is ever a change in how to sign up.
We will first start with signing up from within your Jabber chat application on mobile, where you will never need to leave the client to get set up. I will be using the freedomware Android client Cheogram to do this signup. To star … ⌘ Read more
JMP: Signup with Cheogram Android
Welcome to JMP.chat! If you are looking for a simple guide on how to sign up for JMP, then you have come to the right place! We will be keeping this guide up-to-date if there is ever a change in how to sign up.
We will first start with signing up from within your Jabber chat application on mobile, where you will never need to leave the client to get set up. I will be using the freedomware Android client Cheogram to do this signup. To star … ⌘ Read more
JMP: Signup with Cheogram Android
Welcome to JMP.chat! If you are looking for a simple guide on how to sign up for JMP, then you have come to the right place! We will be keeping this guide up-to-date if there is ever a change in how to sign up.
We will first start with signing up from within your Jabber chat application on mobile, where you will never need to leave the client to get set up. I will be using the freedomware Android client Cheogram to do this signup. To star … ⌘ Read more
Right now I have to setup jenny for my timeline. Just added myself to the Registry so that part is done.
Git’s database internals I: packed object store
This blog series will examine Git’s internals to help make your engineering system more efficient. Part I discusses how Git stores its data in packfiles using custom compression techniques. ⌘ Read more
[47°09′05″S, 126°43′24″W] Bad satellite signal – switching to analog communication
Holding ᵒⁿˡʸ Them to Account ⌘ Read more
[47°09′56″S, 126°43′31″W] Working impossible due to blizzard
[47°09′03″S, 126°43′51″W] Working impossible due to heavy rain
[47°09′17″S, 126°43′18″W] Working impossible due to thunderstorm
[47°09′10″S, 126°43′18″W] Automatic systems disengaged due to blizzard
A 4-minute video about my project to replace debuggers with print statements: https://merveilles.town/@akkartik/108895837561334218
Started my morning with a long walk with the dog, getting very warm today, so if I do not walk in the morning I have to do that in the late evening. So now he’s tired, had breakfast and just chills outside. Nice way to start this Saturday :)
[47°09′27″S, 126°43′22″W] Storm recedes – back to normal work
@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.
@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.
3 ways every company can get started with an open-source software strategy
The future of software development does not exist without open source. However, to maintain today’s software and create the software of the future, the largest organizations and beneficiaries of open source need to expand their collaboration with the community and help it grow. ⌘ Read more
Community All-Hands Q3: What We’ll Cover
Our 6th quarterly Community All-Hands is almost here! Get the inside scoop on what we’ll cover and how to sign up. ⌘ Read more
Mark Zuckerberg on joe rogan , looking forward to hear this later today. I hope Joe is very critical.
Cloud Swirls
⌘ Read more
There’s no #Extramuralhas without a visit to Cardamomo…
There’s no #Extramuralhas without a visit to Cardamomo…
[47°09′05″S, 126°43′19″W] Transponder still failing – switching to analog communication
Keeping your skillset fresh as a developer
Whether you’re committing 30 minutes or 3 hours a day to learning, consistency is key. Klint Finley asks 3 tech professionals at different stages in their career for more advice. ⌘ Read more
**In 2011, @MightySieben in Leiria’s castle for #Entremuralhas .
Today he returns to the castle (this time in Pena’s church) for the kick off concert of #Extramuralhas .
Concert in less than two hours, and I can’t wait!**
In 2011, @MightySieben in Leiria’s castle for #Entremuralhas .
Today he returns to the castle (this time in Pena’s church) for the kick off concert of [#Extramuralhas](https://nitter.net/search? … ⌘ Read more
How to Develop and Deploy a Customer Churn Prediction Model Using Python, Streamlit, and Docker
Customer churn is a million-dollar problem for businesses today. The SaaS market is becoming increasingly saturated, and customers can choose from plenty of providers. Retention and nurturing are challenging. Online businesses view customers as churn when they stop purchasing goods and services. Customer churn can depend on industry-specific factors, y … ⌘ Read more
Introducing Trilogy: a new database adapter for Ruby on Rails
We’ve open sourced Trilogy, the database adapter we use to connect Ruby on Rails to MySQL-compatible database servers. ⌘ Read more
**What’s happening? I’m going to see @MightySieben on #Extramuralhas , that’s what’s happening!
#BifeVolta #SiebenLive #Entremuralhas**
What’s happening? I’m going to see @MightySieben on #Extramuralhas , that’s what’s happening!
#BifeVolta #SiebenLive #Entremuralhas
[nitter.net … ⌘ Read more
Erlang Solutions: Implementing Go Fish to Learn Elixir
A walkthrough of how we implemented GoFish as a way of learning Elixir and the concepts of the BEAM and OTP.
In this article, we will outline our initial design and implementation of the card game Go Fish in Elixir using raw processes, and then describe how we were motivated to re-implement the project using the GenServer module instead. The first step is to agree upon the rules of the game, then describe the domain mode … ⌘ Read more
RT by @mind_booster: There’s a lot of competition for the title of “Most On-The-Nose Symbol of Late Stage Capitalism,” but I think there’s a strong case for awarding the crown to #VaccineApartheid - the decision to deny covid vaccines to billions of poor people in the Global South. 1/
There’s a *lot* of competition for the title of “Most On-The-Nose Symbol of Late Stage Capitalism,” but I think there’s a strong case for awarding the crown to [#VaccineApartheid](https://nitter.net/search?q=%23VaccineAparthei … ⌘ Read more
[47°09′59″S, 126°43′29″W] Bad satellite signal – switching to analog communication
Tetherball Configurations
⌘ Read more
JMP: Newsletter: New Employee, Command UI, JMP SIM Card, Multi-account Billing
Hi everyone!
Welcome to the latest edition of your pseudo-monthly JMP update!
In case it’s been a while since you checked out JMP, here’s a refresher: JMP lets you send and receive text and picture messages (and calls) through a real phone number right from your computer, tablet, phone, or anything else that has a Jabber client. Among other things, JMP has these features: Your phone number on every device; Multiple phone … ⌘ Read more
The full lineup for Git Merge 2022 revealed
We are pleased to announce the full lineup of talks and workshops for this year’s Git Merge conference in Chicago. 17 talks, 3 workshops, 1 panel, and some great company! ⌘ Read more
Apple abandons M1 CPU, moves to RISC-V.
“I mean, come on. We’re Apple. Changing CPU architectures is kinda what we do.” ⌘ Read more
PEP 697: C API for Extending Opaque Types
Add limited C API for extending types whose struct is opaque, by allowing code to only deal with data specific to a particular (sub)class. ⌘ Read more
The 1948 precursor to the hard disk
A brass rotating, magnetic drum… inspired by a voice dictation machine. ⌘ Read more
Erlang Solutions: How Can Technology Answer the Questions Still Unanswered in FinTech?
Leaders in the fintech industry joined us to discuss how technology can answer the remaining questions in fintech. They explored key technologies shaping the sector that could also have an impact on society as a whole. Join our panel moderated by Andrew Vorster (Innovation Catalyst) featuring Jacky Uys (Mambu … ⌘ Read more
Physics Safety Tip
⌘ Read more
re-encoded all videos to play in HTML5 video tags, and added corresponding support to eureka
@lyse@lyse.isobeef.org hah! I cut some out to fit into my pods 4k limit.
Yeah that does studder a bit. To be honest I have no idea what I was thinking there. This excerpt was written a good year ago.
@lyse@lyse.isobeef.org hah! I cut some out to fit into my pods 4k limit.
Yeah that does studder a bit. To be honest I have no idea what I was thinking there. This excerpt was written a good year ago.
** Miscellaneous this and that **
Since my brain injury (which I’ve since learned can be called an“ABI” or“acquired brain injury”) I’ve noticed that I have trouble focusing on programming tasks; I’m able to do what I need to do for work and family but, when it comes time for hobby projects I’m just gloop. Totally oozy.
Because of that I’ve been drawn to do more reading and game playing, but also still wanna code…I’ve found that it is easier to use more“batteries included” kinda languages, namely scheme, over what I’d … ⌘ Read more
@lyse@lyse.isobeef.org I do wonder how we could build a decentralized way to do this 🤔
Good morning to you all, new day is here. Nice with weekend. Today I want to code a bit, and then do some flightsim tonight.
❤️ 🎶: Welcome to MOMOLAND by MOMOLAND
New day at the office, been a nice first week after vacation so far, but weekend is always appreciated!
Not sure what we’re going to do yet - but I’m sure going to enjoy the days off work :)
[47°09′48″S, 126°43′52″W] Bad satellite signal – switching to analog communication
Dino: Stateless File Sharing: Sources and Compatibility
This is my next progress post about my Google Summer of Code project of implementing Stateless File Sharing (sfs)
Like everything else we receive, we need to store the sfs sources in a database.
In this case, we are in a unique position:
Not only are there different kinds of sources, but even http sources on their own are not trivial.
For now, we only … ⌘ Read more
**2 days, 2 laptops to which a new life was given:
1st, an installation of Bodhi Linux on a 14yrs old machine. From unusable to usable - there are no miracles (web browsing is *soheavy nowadays!), but it works.
Then a 10yrs old laptop upgrading from Win8 to Ubuntu 22.04, fresh!**
2 days, 2 laptops to which a new life was given:
1st, an installation of Bodhi Linux on a 14yrs old machine. From unusable to usable - there are no miracles (web browsing is *so*heavy* nowadays!), but it works.
Then a 10yrs ol … ⌘ Read more
**R to @mind_booster: «A Câmara Municipal de Lisboa diz que “não é exequível” fazer cumprir os limites de ruído»
Isto é o mesmo que dizer “candidatamo-nos para o trabalho, mas não conseguimos fazê-lo”. Isto sim, devia ter custos políticos.
Inaceitável. (2/2)**
«A Câmara Municipal de Lisboa diz que “não é exequível” fazer cumprir os limites de ruído»
Isto é o mesmo que dizer “candidatamo-nos para o trabalho, mas não conseguimos fazê-lo”. Isto sim, devia ter custos políticos.
Inaceitável. (2/2) ⌘ Read more
I should have attended the Homebrew Website Club London / Europe in June, after all they talked about maps, a topic I have some experience with. James uses Leaflet to create maps with his visited coffee shops. 👍 ⌘ Read more
I should have attended the Homebrew Website Club London / Europe in June, after all they talked about maps, a topic I have some experience with. James uses Leaflet to create maps with his visited coffee shops. 👍 ⌘ Read more
GitHub Discussions is now available on GitHub Enterprise Server
As part of GitHub Enterprise Server 3.6, enterprise customers will now be able to use GitHub Discussions. ⌘ Read more
How to remember everything you read ⌘ Read more
Shouldn’t it be called Metacountries? After all it is only available to one country at a time…
Shouldn’t it be called Metacountries? After all it is only available to one country at a time…
nitter.net/ChrisJBakke/status/1559696878530449418#m ⌘ Read more
Who did this to my face? 🤔 ⌘ Read more
Gen Z
⌘ Read more
How To Count In Binary | Neil deGrasse Tyson Explains… ⌘ Read more
2022 Transparency Report: January to June
We’re reporting on a six-month period rather than annually to increase our level of transparency. For this report, we’ve continued with the more granular reporting we began in our 2021 reports. ⌘ Read more
The BBS is back On-Line, with more games a-comin’!
One of the chief goals of The House of Lunduke BBS is to preserve the best of 1980’s and 1990s BBS gaming — in all its ANSI, colorful text art glory. With that goal in mind, I recently took the BBS Off-Line for a much needed retro-fit… in order to properly accommodate a wider selection of classic BBS “Door” Games. ⌘ Read more
👋 Hello @burglar@txt.sour.is, welcome to txt.sour.is, a Yarn.social Pod! To get started you may want to check out the pod’s Discover feed to find users to follow and interact with. To follow new users, use the ⨁ Follow button on their profile page or use the Follow form and enter a Twtxt URL. You may also find other feeds of interest via Feeds. Welcome! 🤗
👋 Hello @burglar@txt.sour.is, welcome to txt.sour.is, a Yarn.social Pod! To get started you may want to check out the pod’s Discover feed to find users to follow and interact with. To follow new users, use the ⨁ Follow button on their profile page or use the Follow form and enter a Twtxt URL. You may also find other feeds of interest via Feeds. Welcome! 🤗
Lunduke’s History of Computers - Volume 2
Free for all subscribers to The Lunduke Journal. ⌘ Read more
Public Service Announcement: Fear not, we’re still on patrol and ask you to keep a close eye on your Yarn neighborhood. We got some reports of suspicious activities going on in the background lately.
I was just about to write a long response to a discussion I saw online. But while writing it, I realized that I have an opinion, but I can’t express it properly and somehow I don’t have anything to contribute. So I deleted my draft. I don’t have to give my two cents on everything. 😅 ⌘ Read more
[47°09′45″S, 126°43′11″W] Storm recedes – back to normal work
The next step for LGTM.com: GitHub code scanning!
Today, GitHub code scanning has all of LGTM.com’s key features—and more! The time has therefore come to announce the plan for the gradual deprecation of LGTM.com. ⌘ Read more
I’ve realized that trying to strictly follow what is on the IndieWeb wiki won’t work well for me. Thus, I have to invent and change some things to make it work better. ⌘ Read more
(cont.)
Just to give some context on some of the components around the code structure.. I wrote this up around an earlier version of aggregate code. This generic bit simplifies things by removing the need of the Crud functions for each aggregate.
Domain ObjectsA domain object can be used as an aggregate by adding the event.AggregateRoot struct and finish implementing event.Aggregate. The AggregateRoot implements logic for adding events after they are either Raised by a command or Appended by the eventstore Load or service ApplyFn methods. It also tracks the uncommitted events that are saved using the eventstore Save method.
type User struct {
Identity string ```json:"identity"`
CreatedAt time.Time
event.AggregateRoot
}
// StreamID for the aggregate when stored or loaded from ES.
func (a *User) StreamID() string {
return "user-" + a.Identity
}
// ApplyEvent to the aggregate state.
func (a *User) ApplyEvent(lis ...event.Event) {
for _, e := range lis {
switch e := e.(type) {
case *UserCreated:
a.Identity = e.Identity
a.CreatedAt = e.EventMeta().CreatedDate
/* ... */
}
}
}
Events
Events are applied to the aggregate. They are defined by adding the event.Meta and implementing the getter/setters for event.Event
type UserCreated struct {
eventMeta event.Meta
Identity string
}
func (c *UserCreated) EventMeta() (m event.Meta) {
if c != nil {
m = c.eventMeta
}
return m
}
func (c *UserCreated) SetEventMeta(m event.Meta) {
if c != nil {
c.eventMeta = m
}
}
Reading Events from EventStore
With a domain object that implements the event.Aggregate the event store client can load events and apply them using the Load(ctx, agg) method.
// GetUser populates an user from event store.
func (rw *User) GetUser(ctx context.Context, userID string) (*domain.User, error) {
user := &domain.User{Identity: userID}
err := rw.es.Load(ctx, user)
if err != nil {
if err != nil {
if errors.Is(err, eventstore.ErrStreamNotFound) {
return user, ErrNotFound
}
return user, err
}
return nil, err
}
return user, err
}
OnX Commands
An OnX command will validate the state of the domain object can have the command performed on it. If it can be applied it raises the event using event.Raise() Otherwise it returns an error.
// OnCreate raises an UserCreated event to create the user.
// Note: The handler will check that the user does not already exsist.
func (a *User) OnCreate(identity string) error {
event.Raise(a, &UserCreated{Identity: identity})
return nil
}
// OnScored will attempt to score a task.
// If the task is not in a Created state it will fail.
func (a *Task) OnScored(taskID string, score int64, attributes Attributes) error {
if a.State != TaskStateCreated {
return fmt.Errorf("task expected created, got %s", a.State)
}
event.Raise(a, &TaskScored{TaskID: taskID, Attributes: attributes, Score: score})
return nil
}
Crud Operations for OnX Commands
The following functions in the aggregate service can be used to perform creation and updating of aggregates. The Update function will ensure the aggregate exists, where the Create is intended for non-existent aggregates. These can probably be combined into one function.
// Create is used when the stream does not yet exist.
func (rw *User) Create(
ctx context.Context,
identity string,
fn func(*domain.User) error,
) (*domain.User, error) {
session, err := rw.GetUser(ctx, identity)
if err != nil && !errors.Is(err, ErrNotFound) {
return nil, err
}
if err = fn(session); err != nil {
return nil, err
}
_, err = rw.es.Save(ctx, session)
return session, err
}
// Update is used when the stream already exists.
func (rw *User) Update(
ctx context.Context,
identity string,
fn func(*domain.User) error,
) (*domain.User, error) {
session, err := rw.GetUser(ctx, identity)
if err != nil {
return nil, err
}
if err = fn(session); err != nil {
return nil, err
}
_, err = rw.es.Save(ctx, session)
return session, err
}
(cont.)
Just to give some context on some of the components around the code structure.. I wrote this up around an earlier version of aggregate code. This generic bit simplifies things by removing the need of the Crud functions for each aggregate.
Domain ObjectsA domain object can be used as an aggregate by adding the event.AggregateRoot struct and finish implementing event.Aggregate. The AggregateRoot implements logic for adding events after they are either Raised by a command or Appended by the eventstore Load or service ApplyFn methods. It also tracks the uncommitted events that are saved using the eventstore Save method.
type User struct {
Identity string ```json:"identity"`
CreatedAt time.Time
event.AggregateRoot
}
// StreamID for the aggregate when stored or loaded from ES.
func (a *User) StreamID() string {
return "user-" + a.Identity
}
// ApplyEvent to the aggregate state.
func (a *User) ApplyEvent(lis ...event.Event) {
for _, e := range lis {
switch e := e.(type) {
case *UserCreated:
a.Identity = e.Identity
a.CreatedAt = e.EventMeta().CreatedDate
/* ... */
}
}
}
Events
Events are applied to the aggregate. They are defined by adding the event.Meta and implementing the getter/setters for event.Event
type UserCreated struct {
eventMeta event.Meta
Identity string
}
func (c *UserCreated) EventMeta() (m event.Meta) {
if c != nil {
m = c.eventMeta
}
return m
}
func (c *UserCreated) SetEventMeta(m event.Meta) {
if c != nil {
c.eventMeta = m
}
}
Reading Events from EventStore
With a domain object that implements the event.Aggregate the event store client can load events and apply them using the Load(ctx, agg) method.
// GetUser populates an user from event store.
func (rw *User) GetUser(ctx context.Context, userID string) (*domain.User, error) {
user := &domain.User{Identity: userID}
err := rw.es.Load(ctx, user)
if err != nil {
if err != nil {
if errors.Is(err, eventstore.ErrStreamNotFound) {
return user, ErrNotFound
}
return user, err
}
return nil, err
}
return user, err
}
OnX Commands
An OnX command will validate the state of the domain object can have the command performed on it. If it can be applied it raises the event using event.Raise() Otherwise it returns an error.
// OnCreate raises an UserCreated event to create the user.
// Note: The handler will check that the user does not already exsist.
func (a *User) OnCreate(identity string) error {
event.Raise(a, &UserCreated{Identity: identity})
return nil
}
// OnScored will attempt to score a task.
// If the task is not in a Created state it will fail.
func (a *Task) OnScored(taskID string, score int64, attributes Attributes) error {
if a.State != TaskStateCreated {
return fmt.Errorf("task expected created, got %s", a.State)
}
event.Raise(a, &TaskScored{TaskID: taskID, Attributes: attributes, Score: score})
return nil
}
Crud Operations for OnX Commands
The following functions in the aggregate service can be used to perform creation and updating of aggregates. The Update function will ensure the aggregate exists, where the Create is intended for non-existent aggregates. These can probably be combined into one function.
// Create is used when the stream does not yet exist.
func (rw *User) Create(
ctx context.Context,
identity string,
fn func(*domain.User) error,
) (*domain.User, error) {
session, err := rw.GetUser(ctx, identity)
if err != nil && !errors.Is(err, ErrNotFound) {
return nil, err
}
if err = fn(session); err != nil {
return nil, err
}
_, err = rw.es.Save(ctx, session)
return session, err
}
// Update is used when the stream already exists.
func (rw *User) Update(
ctx context.Context,
identity string,
fn func(*domain.User) error,
) (*domain.User, error) {
session, err := rw.GetUser(ctx, identity)
if err != nil {
return nil, err
}
if err = fn(session); err != nil {
return nil, err
}
_, err = rw.es.Save(ctx, session)
return session, err
}
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
}
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)
})
I can tell the function the type being modified and returned using the function argument that is passed in. pretty cray cray.
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
}
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)
})
I can tell the function the type being modified and returned using the function argument that is passed in. pretty cray cray.
If you want good grades, study. If you want to lose weight, exercise. If you want to communicate, make an effort. 100+ Quotes From “Extraordinary Attorney Woo” – KORB
by which the future life expectancy of some non-perishable things, like a technology or an idea, is proportional to their current age. Thus, the Lindy effect proposes the longer a period something has survived to exist or be used in the present, the longer its remaining life expectancy. The disproportionate influence of early tech decisions — brandur.org
[47°09′15″S, 126°43′12″W] Bad satellite signal – switching to analog communication
Tomorrow I go back to the office after 4 weeks off, going to be rough to get up in the morning :p
The XMPP Standards Foundation: Mid Term Evaluation Updates
It’s been a month since I wrote my last blog. For those of you who have been following my blogs, thanks a lot for taking the time to read them. In this blog, I will give the updates post mid-term evaluation and the challenges that I have been facing and how I overcame some of them.
For those of you who don’t know much about GSoC, a mid-term evaluat … ⌘ Read more
Tailscale SSH
I finally got around to using Tailscale SSH. I’ve been using Tailscale for over a year to access my servers via SSH (my VPS is even available via Tailscale only), but I haven’t used the new Tailscale SSH feature yet. ⌘ Read more
With respect to logging.. oh man.. it really depends on the environment you are working in.. development? log everything! and use a jeager open trace for the super gnarly places. So you can see whats going on while building. But, for production? metrics are king. I don’t want to sift through thousands of lines but have a measure that can tell me the health of the service.
With respect to logging.. oh man.. it really depends on the environment you are working in.. development? log everything! and use a jeager open trace for the super gnarly places. So you can see whats going on while building. But, for production? metrics are king. I don’t want to sift through thousands of lines but have a measure that can tell me the health of the service.
“They Don’t Want to Hear the Truth” -John Barilaro href=”https://txt.sour.is/search?q=%23shorts”>#shorts** ⌘ Read more
The History of Ctrl-Alt-Delete
How the “Three Fingered Salute” came to be. ⌘ Read more
@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.
RT by @mind_booster: Two related stories this month show capitalism’s incompatibility with human and non-human flourishing. First, a study found all rainwater on earth is unsafe to drink because it’s contaminated with the ‘forever chemicals’ Per- and poly-fluoroalkyl (PFAS). 🧵https://www.euronews.com/green/2022/08/04/rainwater-everywhere-on-earth-unsafe-to-drink-due-to-forever-chemicals-study-finds
Two related stories this month show capitalism’s incompatibility with human and non-human flourishing. First, a st … ⌘ Read more
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.
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.
Another flaw in the human character is that everybody wants to build and nobody wants to do maintenance “Another flaw in the human character is that everybody wants to build and nobody wants to do maintenance”*… | (Roughly) Daily
GitHub Pages now uses Actions by default
As GitHub Pages, home to 16 million websites, approaches its 15th anniversary, we’re excited to announce that all sites now build and deploy with GitHub Actions. ⌘ Read more
The ‘West’ is losing. How could it not?
I’m pretty sure that February 24th, 2022 is going to be written in the history books, if those books ever get written and we’re not all subsumed in an imminent nuclear winter. The predictability of a Europe, and later United States-dominated world, where the ‘West’ ruled and enjoyed unprecedented levels of comfort, material wealth and peace and the rest of the world either suffered or gradually developed, feeding from the leftovers of Western consumption, i … ⌘ Read more
[47°09′48″S, 126°43′01″W] Storm recedes – back to normal work
[47°09′45″S, 126°43′40″W] Working impossible due to blizzard
Dependabot now alerts for vulnerable GitHub Actions
GitHub Actions gives teams access to powerful, native CI/CD capabilities right next to their code hosted in GitHub. Starting today, GitHub will send a Dependabot alert for vulnerable GitHub Actions, making it even easier to stay up to date and fix security vulnerabilities in your actions workflows. ⌘ Read more
Also later today I need to set up that startupscript for yarnd, tired of manually starting it when vps boots.
The US put tornadocash on sanction list. Deleted github accounts and source. Since North Korea used it to launder stolen crypto.
And people are surprised that it happened? Github is and never have been a safe place to store code. Tor/i2p is much more safer places to host code. But I understand why people use github, I do so as well for public project, but I also selfhost my other things