[47°09′59″S, 126°43′14″W] Transponder still failing – switching to analog communication
[47°09′03″S, 126°43′53″W] Dosimeter still failing
[47°09′05″S, 126°43′51″W] Dosimeter still failing
[47°09′23″S, 126°43′35″W] Dosimeter still failing
[47°09′07″S, 126°43′30″W] Transponder still failing – switching to analog communication
[47°09′59″S, 126°43′15″W] Transponder still failing
[47°09′55″S, 126°43′12″W] Dosimeter still failing
[47°09′45″S, 126°43′01″W] Transponder still failing – switching to analog communication
Question to all you Gophers out there: How do you deal with custom errors that include more information and different kinds of matching them?
I started with a simple var ErrPermissionNotAllowed = errors.New("permission not allowed"). In my function I then wrap that using fmt.Errorf("%w: %v", ErrPermissionNotAllowed, failedPermissions). I can match this error using errors.Is(err, ErrPermissionNotAllowed). So far so good.
Now for display purposes I’d also like to access the individual permissions that could not be assigned. Parsing the error message is obviously not an option. So I thought, I create a custom error type, e.g. type PermissionNotAllowedError []Permission and give it some func (e PermissionNotAllowedError) Error() string { return fmt.Sprintf("permission not allowed: %v", e) }. My function would then return this error instead: PermissionNotAllowedError{failedPermissions}
At some layers I don’t care about the exact permissions that failed, but at others I do, at least when accessing them. A custom func (e PermissionNotAllowedError) Is(target err) bool could match both the general ErrPermissionNotAllowed as well as the PermissionNotAllowedError. Same with As(…). For testing purposes the PermissionNotAllowedError would then also try to match the included permissions, so assertions in tests would work nicely. But having two different errors for different matching seems not very elegant at all.
Did you ever encounter this scenario before? How did you address this? Is my thinking flawed?
[47°09′25″S, 126°43′02″W] Transponder still failing – switching to analog communication
[47°09′56″S, 126°43′56″W] Transponder still failing – switching to analog communication
[47°09′42″S, 126°43′01″W] Transponder still failing
[47°09′47″S, 126°43′00″W] Transponder still failing – switching to analog communication
[47°09′11″S, 126°43′25″W] Transponder still failing
[47°09′17″S, 126°43′04″W] Dosimeter still failing
[47°09′10″S, 126°43′13″W] Transponder still failing
[47°09′36″S, 126°43′12″W] Dosimeter still failing
[47°09′19″S, 126°43′35″W] Transponder still failing – switching to analog communication
@prologic@twtxt.net Yeah, we had some discussion about it once it was announced. I said what I felt (And I do love VR - but for flight simulators etc) - but I just knew it would fail.
Especially when they showed the ridiculous screenshots that they where so proud of with the quality of 15 years ago.
And they they pushed it as a place to work or have meetings during the pandemic.. haha.
And they did not even use it themselves in the company.
[47°09′17″S, 126°43′47″W] Transponder still failing – switching to analog communication
[47°09′33″S, 126°43′02″W] Dosimeter still failing
[47°09′44″S, 126°43′29″W] Dosimeter still failing
[47°09′48″S, 126°43′35″W] Transponder still failing – switching to analog communication
[47°09′35″S, 126°43′54″W] Dosimeter still failing
[47°09′47″S, 126°43′34″W] Transponder still failing – switching to analog communication
[47°09′42″S, 126°43′30″W] Dosimeter still failing
[47°09′19″S, 126°43′12″W] Transponder still failing
Why is Firefox called Firefox?
A story of bullying, and failing to see if a product name is in use before choosing it. ⌘ Read more
[47°09′43″S, 126°43′06″W] Transponder still failing
@funbreaker@twtxt.net Could you pull the latest code and rebuild? I have added SSL verification now.
If it still fails I’ll make a twtxt account and look into it more.
@lyse@lyse.isobeef.org @prologic@twtxt.net it seems like the ssl verification works now, I enabled it - but also added another option as well that I now saw in the docs, and now it did not fail on my end (which it did before). I will add a ‘enable ssl verification’ checkbox (checked by default) so that those who do not need or want it for testing and such can disable it if they want.
[47°09′57″S, 126°43′11″W] Dosimeter still failing
[47°09′21″S, 126°43′56″W] Transponder still failing – switching to analog communication
[47°09′59″S, 126°43′48″W] Dosimeter still failing
[47°09′05″S, 126°43′31″W] Transponder still failing – switching to analog communication
Erlang Solutions: 5 Key Tech Priorities for Fintech Leaders in 2023
The fintech industry is a major disruptor. Each year, it impacts how consumers interact with financial companies and brings new and innovative means to meet ever-growing customer expectations and occupy market space.
As a business owner or executive in this space, you have no choice but to stay on top of your game to increase efficiency.
In simpler terms, if your business doesn’t scale, it could fail.
That mig … ⌘ Read more
[47°09′41″S, 126°43′15″W] Dosimeter still failing
SUSE CEO out effective immediately, replacement CEO not available until later.
A failed IPO, political attacks, and purchased “awards” are the legacy of the departing CEO of the oldest Linux company. ⌘ Read more
[47°09′21″S, 126°43′27″W] Dosimeter still failing
[47°09′00″S, 126°43′49″W] Transponder still failing – switching to analog communication
[47°09′04″S, 126°43′59″W] Transponder still failing
[47°09′25″S, 126°43′28″W] Dosimeter still failing
@prologic@twtxt.net Thank you.
What I did was to just pull the latest, build deps and the server, then enable the features as you mention through command line, as soon as I add activitypub it fails with that error when it starts up.
[47°09′34″S, 126°43′29″W] Transponder still failing – switching to analog communication
[47°09′43″S, 126°43′12″W] Transponder still failing
[47°09′00″S, 126°43′02″W] Dosimeter still failing
[47°09′41″S, 126°43′33″W] Transponder still failing – switching to analog communication
[47°09′03″S, 126°43′43″W] Dosimeter still failing
[47°09′19″S, 126°43′12″W] Transponder still failing – switching to analog communication
@eldersnake@we.loveprivacy.club Several reasons:
- It’s another language to learn (SQL)
- It adds another dependency to your system
- It’s another failure mode (database blows up, scheme changes, indexs, etc)
- It increases security problems (now you have to worry about being SQL-safe)
And most of all, in my experience, it doesn’t actually solve any problems that a good key/value store can solve with good indexes and good data structures. I’m just no longer a fan, I used to use MySQL, SQLite, etc back in the day, these days, nope I wouldn’t even go anywhere near a database (for my own projects) if I can help it – It’s just another thing that can fail, another operational overhead.
[47°09′33″S, 126°43′41″W] Transponder still failing – switching to analog communication
[47°09′21″S, 126°43′50″W] Transponder still failing – switching to analog communication
[47°09′04″S, 126°43′23″W] Transponder still failing
[47°09′43″S, 126°43′16″W] Transponder still failing – switching to analog communication
[47°09′14″S, 126°43′19″W] Transponder still failing – switching to analog communication
Anyone know what this might be about?
[1134036.271114] ata1.00: exception Emask 0x0 SAct 0x4 SErr 0x880000 action 0x6 frozen
[1134036.271478] ata1: SError: { 10B8B LinkSeq }
[1134036.271829] ata1.00: failed command: WRITE FPDMA QUEUED
[1134036.272182] ata1.00: cmd 61/20:10:e0:75:6e/00:00:11:00:00/40 tag 2 ncq 16384 out
res 40/00:01:00:4f:c2/00:00:00:00:00/00 Emask 0x4 (timeout)
[1134036.272895] ata1.00: status: { DRDY }
[1134036.273245] ata1: hard resetting link
[1134037.447033] ata1: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
[1134038.747174] ata1.00: configured for UDMA/133
[1134038.747179] ata1.00: device reported invalid CHS sector 0
[1134038.747185] ata1: EH complete
[47°09′01″S, 126°43′44″W] Dosimeter still failing
[47°09′51″S, 126°43′26″W] Transponder still failing – switching to analog communication
[47°09′44″S, 126°43′23″W] Transponder still failing
[47°09′18″S, 126°43′58″W] Transponder still failing – switching to analog communication
[47°09′07″S, 126°43′28″W] Dosimeter still failing
[47°09′29″S, 126°43′10″W] Dosimeter still failing
[47°09′22″S, 126°43′59″W] Transponder still failing – switching to analog communication
[47°09′42″S, 126°43′21″W] Transponder still failing – switching to analog communication
$name$ and then dispatch the hashing or checking to its specific format.
Here is an example of usage:
func Example() {
pass := "my_pass"
hash := "my_pass"
pwd := passwd.New(
&unix.MD5{}, // first is preferred type.
&plainPasswd{},
)
_, err := pwd.Passwd(pass, hash)
if err != nil {
fmt.Println("fail: ", err)
}
// Check if we want to update.
if !pwd.IsPreferred(hash) {
newHash, err := pwd.Passwd(pass, "")
if err != nil {
fmt.Println("fail: ", err)
}
fmt.Println("new hash:", newHash)
}
// Output:
// new hash: $1$81ed91e1131a3a5a50d8a68e8ef85fa0
}
This shows how one would set a preferred hashing type and if the current version of ones password is not the preferred type updates it to enhance the security of the hashed password when someone logs in.
https://github.com/sour-is/go-passwd/blob/main/passwd_test.go#L33-L59
$name$ and then dispatch the hashing or checking to its specific format.
Here is an example of usage:
func Example() {
pass := "my_pass"
hash := "my_pass"
pwd := passwd.New(
&unix.MD5{}, // first is preferred type.
&plainPasswd{},
)
_, err := pwd.Passwd(pass, hash)
if err != nil {
fmt.Println("fail: ", err)
}
// Check if we want to update.
if !pwd.IsPreferred(hash) {
newHash, err := pwd.Passwd(pass, "")
if err != nil {
fmt.Println("fail: ", err)
}
fmt.Println("new hash:", newHash)
}
// Output:
// new hash: $1$81ed91e1131a3a5a50d8a68e8ef85fa0
}
This shows how one would set a preferred hashing type and if the current version of ones password is not the preferred type updates it to enhance the security of the hashed password when someone logs in.
https://github.com/sour-is/go-passwd/blob/main/passwd_test.go#L33-L59
[47°09′03″S, 126°43′26″W] Dosimeter still failing
In this House — We might fail, but never with abandon — Every moment is fresh, unimpeded by the one before — We remove as many obligations as we add — There is something to protect, something to give everything for — Tsuyoku Naritai!
[47°09′07″S, 126°43′48″W] Transponder still failing
[47°09′55″S, 126°43′02″W] Dosimeter still failing
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
Not sure if the issue is on my end or the other..
of course the Soviet Union failed—they didn’t have computers yet!
[47°09′39″S, 126°43′05″W] Dosimeter still failing
[47°09′36″S, 126°43′46″W] Transponder still failing – switching to analog communication
[47°09′54″S, 126°43′16″W] Transponder still failing
[47°09′31″S, 126°43′41″W] Dosimeter still failing
[47°09′46″S, 126°43′22″W] Dosimeter still failing
[47°09′29″S, 126°43′05″W] Transponder still failing – switching to analog communication
[47°09′45″S, 126°43′00″W] Transponder still failing
[47°09′20″S, 126°43′47″W] Transponder still failing
[47°09′32″S, 126°43′47″W] Dosimeter still failing
[47°09′42″S, 126°43′25″W] Dosimeter still failing
[47°09′03″S, 126°43′14″W] Transponder still failing – switching to analog communication
[47°09′07″S, 126°43′38″W] Transponder still failing – switching to analog communication
[47°09′13″S, 126°43′34″W] Transponder still failing – switching to analog communication
[47°09′25″S, 126°43′52″W] Dosimeter still failing
[47°09′05″S, 126°43′31″W] Transponder still failing – switching to analog communication
[47°09′39″S, 126°43′56″W] Dosimeter still failing
Before Chromebooks: The 2009 “litl webbook”
A look back at the failed, Linux “Web-book” that paved the way for Chromebooks. ⌘ Read more
[47°09′05″S, 126°43′19″W] Transponder still failing – switching to analog communication
[47°09′35″S, 126°43′10″W] Transponder still failing
[47°09′00″S, 126°43′23″W] Dosimeter still failing
[47°09′57″S, 126°43′16″W] Transponder still failing
(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
}
if you fail in a way that is common, nobody blames you Ask HN: Why did smartphones become a single point of failure? | Hacker News
[47°09′01″S, 126°43′48″W] Dosimeter still failing
[47°09′27″S, 126°43′21″W] Transponder still failing
[47°09′16″S, 126°43′18″W] Dosimeter still failing
[47°09′49″S, 126°43′59″W] Transponder still failing – switching to analog communication