🧮 USERS:1 FEEDS:2 TWTS:333 ARCHIVED:36357 CACHE:1579 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:332 ARCHIVED:36316 CACHE:1563 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:331 ARCHIVED:36304 CACHE:1600 FOLLOWERS:13 FOLLOWING:14
Realmente, custa muito a entender. Dissecar esta notícia dava uma tese, mas não tentar expandir-me muito sobre isto só me daria cabo dos nervos. Fico-me pelo início: (½)
Realmente, custa muito a entender. Dissecar esta notícia dava uma tese, mas não tentar expandir-me muito sobre isto só me daria cabo dos nervos. Fico-me pelo início: (½)
nitter.net/paulasimoes/status/1560221281198432256#m ⌘ Read more
🧮 USERS:1 FEEDS:2 TWTS:330 ARCHIVED:36287 CACHE:1596 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:329 ARCHIVED:36277 CACHE:1614 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:328 ARCHIVED:36263 CACHE:1622 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:327 ARCHIVED:36241 CACHE:1665 FOLLOWERS:13 FOLLOWING:14
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.
🧮 USERS:1 FEEDS:2 TWTS:326 ARCHIVED:36217 CACHE:1658 FOLLOWERS:13 FOLLOWING:14
[47°09′42″S, 126°43′03″W] Reading: 1.86 Sv
🧮 USERS:1 FEEDS:2 TWTS:325 ARCHIVED:36174 CACHE:1662 FOLLOWERS:13 FOLLOWING:14
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.
+1
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.
+1
**RT by @mind_booster: [¼]
Terminou ontem a consulta pública do projeto Aproveitamento Hidráulico de Fins Múltiplos do Crato (Barragem do Crato) a que a ZERO dá parecer negativo
❌Dinheiro do PRR vai ser usado p/ projeto sem sentido e promotor de impactes ambientais e sociais negativos
👇(continua)**
[¼]
Terminou ontem a consulta pública do projeto Aproveitamento Hidráulico de Fins Múltiplos do Crato (Barragem do Crato) a que a ZERO dá parecer negativo
❌Dinheiro do PRR vai ser usado p/ projeto sem sentido e p … ⌘ Read more
[47°09′51″S, 126°43′36″W] Reading: 1.22 Sv
🧮 USERS:1 FEEDS:2 TWTS:324 ARCHIVED:36126 CACHE:1630 FOLLOWERS:13 FOLLOWING:14
@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.
🧮 USERS:1 FEEDS:2 TWTS:323 ARCHIVED:36095 CACHE:1620 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:322 ARCHIVED:36071 CACHE:1610 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:321 ARCHIVED:36041 CACHE:1614 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:320 ARCHIVED:36015 CACHE:1629 FOLLOWERS:13 FOLLOWING:14
Scientific Field Prefixes
⌘ Read more
🧮 USERS:1 FEEDS:2 TWTS:319 ARCHIVED:35977 CACHE:1621 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:318 ARCHIVED:35951 CACHE:1608 FOLLOWERS:13 FOLLOWING:14
**RT by @mind_booster: [¼]
✈️Novo passo na expansão ilegal do Aeroporto da Portela prejudicará severamente milhares de cidadãos.
⚠️Foi iniciado processo de consulta pública sobre portaria que passará a permitir voos noturnos sem limites.
(Continua 👇)**
[¼]
✈️Novo passo na expansão ilegal do Aeroporto da Portela prejudicará severamente milhares de cidadãos.
⚠️Foi iniciado processo de consulta pública sobre portaria que passará a permitir voos noturnos sem limites.
(Continua 👇)
. It also updates a number of library dependencies.
The updated plugin should be available for download in your Openfire admin console already. Alternatively, you can download the plugin directly, from [the plugin’s archive page](https://www.ign … ⌘ Read more
🧮 USERS:1 FEEDS:2 TWTS:303 ARCHIVED:35163 CACHE:1475 FOLLOWERS:13 FOLLOWING:14
[47°09′11″S, 126°43′43″W] Reading: 1.77 Sv
[47°09′58″S, 126°43′43″W] Reading: 1.69000 PPM
🧮 USERS:1 FEEDS:2 TWTS:302 ARCHIVED:35148 CACHE:1473 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:301 ARCHIVED:35133 CACHE:1463 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:300 ARCHIVED:35117 CACHE:1470 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:299 ARCHIVED:35064 CACHE:1473 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:298 ARCHIVED:35034 CACHE:1450 FOLLOWERS:13 FOLLOWING:14
I’m trying to switch from Konversation to irssi. Let’s see how that goes. Any irssiers out there who can recommend specific settings or scripts? I already got myself trackbar.pl and nickcolor.pl as super-essentials. Also trying window_switcher.pl. Somehow my custom binds for Ctrl+1/2/3/etc. to switch to window 1/2/3/etc. doesn’t do anything: { key = "^1"; id = "change_window"; data = "1"; } (I cannot use the default with Alt as this is handled by my window manager). Currently, I’m just cycling with Ctrl+N/P. Other things to solve in the near future:
- better, more colorful and compact theme (just removed clock from statusbar so far)
- getting bell/urgency hints working on arriving messages
- nicer tabs in status bar, maybe even just channel names and no indexes
- decluster status bar with user and channel modes (I never cared about those in the last decade)
🧮 USERS:1 FEEDS:2 TWTS:297 ARCHIVED:35006 CACHE:1434 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:296 ARCHIVED:34976 CACHE:1413 FOLLOWERS:13 FOLLOWING:14
Erlang Solutions: Updates to the MIM Inbox in version 5.1
User interfaces in open protocolsWhen a messaging client starts, it typically presents the user with:
- an inbox
- a summary of chats (in chronological order)
- unread messages in their conversation
- a snippet of the most recent message in the conversation
- information on if a conversation is muted (and if so how long a conversation is muted for)
- other information that users may find useful on their welcome screen
Mongoos … ⌘ Read more
❤️ 🎶: Carry On (From “신의”), Pt. 1. - Original Television Soundtrack by ALi
🧮 USERS:1 FEEDS:2 TWTS:295 ARCHIVED:34938 CACHE:1394 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:294 ARCHIVED:34917 CACHE:1389 FOLLOWERS:13 FOLLOWING:14
@prologic@twtxt.net: 1. I use classic twtxt client written in Python from console, I like simplicity; 2. Thanks for the feedback about my website! It’s better viewed with old 800x600 monitors, haha
🧮 USERS:1 FEEDS:2 TWTS:293 ARCHIVED:34885 CACHE:1387 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:292 ARCHIVED:34863 CACHE:1384 FOLLOWERS:13 FOLLOWING:14
Finally started Stranger Things and watched episodes 1 to 5 so far, I quite like it.
🧮 USERS:1 FEEDS:2 TWTS:291 ARCHIVED:34842 CACHE:1418 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:290 ARCHIVED:34827 CACHE:1421 FOLLOWERS:13 FOLLOWING:14
[47°09′21″S, 126°43′22″W] Reading: 1.56000 PPM
🧮 USERS:1 FEEDS:2 TWTS:289 ARCHIVED:34810 CACHE:1428 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:288 ARCHIVED:34804 CACHE:1427 FOLLOWERS:13 FOLLOWING:14
Gajim: Gajim 1.4.6
Gajim 1.4.6 fixes some bugs with the status icon and notifications. Emoji short code detection has been improved.
Several issues have been fixed in this release.
- Improved detection of emoji short codes
- Tray icon with
libappindicatorhas been fixed
- Groups are now preserved when changing a contact’s name
- Windows: Notifications shouldn’t appear in the taskbar anymore
Have a look at the [chan … ⌘ Read more
Ignite Realtime Blog: Push Notification Openfire plugin 0.9.1 released
The Ignite Realtime community is happy to announce the immediate availability of a bugfix release for the Push Notification plugin for Openfire!
This plugin adds support for sending push notifications to client software, as described in XEP-0357: “Push Notifications”.
[This update](https://www.igniterealtime.org/projects/openfire/plugins/0.9.1/pushnotificatio … ⌘ Read more
🧮 USERS:1 FEEDS:2 TWTS:287 ARCHIVED:34793 CACHE:1449 FOLLOWERS:13 FOLLOWING:14
**RT by @mind_booster: My latest @locusmag column is “The Swerve,” a short essay about the shape that hope takes when happy endings are off the table:
https://locusmag.com/2022/07/cory-doctorow-the-swerve/ 1/**
My latest @locusmag column is “The Swerve,” a short essay about the shape that hope takes when happy endings are off the table:
🧮 USERS:1 FEEDS:2 TWTS:286 ARCHIVED:34787 CACHE:1461 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:285 ARCHIVED:34767 CACHE:1465 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:284 ARCHIVED:34741 CACHE:1467 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:283 ARCHIVED:34725 CACHE:1489 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:282 ARCHIVED:34707 CACHE:1492 FOLLOWERS:13 FOLLOWING:14
Last chance for a 1-on-1 video chat with Lunduke
The 1-on-1 perk is being retired after tomorrow! ⌘ Read more
[47°09′48″S, 126°43′06″W] Reading: 1.61 Sv
🧮 USERS:1 FEEDS:2 TWTS:281 ARCHIVED:34685 CACHE:1484 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:280 ARCHIVED:34669 CACHE:1493 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:279 ARCHIVED:34650 CACHE:1498 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:278 ARCHIVED:34640 CACHE:1502 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:277 ARCHIVED:34627 CACHE:1503 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:276 ARCHIVED:34470 CACHE:1475 FOLLOWERS:13 FOLLOWING:14
[47°09′34″S, 126°43′05″W] Reading: 1.46000 PPM
🧮 USERS:1 FEEDS:2 TWTS:275 ARCHIVED:34441 CACHE:1479 FOLLOWERS:13 FOLLOWING:14
Ignite Realtime Blog: REST API Openfire plugin 1.8.1 released!
Earlier today, version 1.8.1 of the Openfire REST API plugin was released. This version removes the need to authenticate for status endpoints, adds new endpoints for bulk modifications of affiliations on MUC rooms, as well as a healthy number of other bugfixes.
The updated plugin should become available for download in your Openfire admin console in the course of the next few hours. Alternatively, you can download the pl … ⌘ Read more
🧮 USERS:1 FEEDS:2 TWTS:274 ARCHIVED:34430 CACHE:1492 FOLLOWERS:13 FOLLOWING:14
[47°09′59″S, 126°43′13″W] Reading: 1.22000 PPM
Erlang Solutions: Contract Programming an Elixir approach – Part 1
This series explores the concepts found in Contract Programming and adapts them to the Elixir language. Erlang and BEAM languages, in general, are surrounded by philosophies like “fail fast”, “defensive programming”, and “offensive programming”, and contract programming can be a nice addition. The series is also available on Github.
You will find a lot … ⌘ Read more