¿Vives en Canadá 🇨🇦? Suena demasiado frio para mí 🥶 Mi hermano quería ir allá a trabajar, y tengo algunos amigos, pero con mi frío de 8° C ya me estoy congelando aquí al norte de México!
¡Me da mucha curiosidad como pueden soportar los autos tanto frío! Me toco manejar en la nieve en Minnesota, aunque quizás no es tanto como lo que soporta el tuyo…
Estoy practicando Ruby con el libro Head First (muy recomendado), y me doy cuenta que es bastante diferente a otros lenguajes que conozco y me gustan como Python, JS, C#. Le estoy apostando sobre Go, PHP y otros. Espero sea buena decisión
(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
}
lolol actually, I’m now building a quick’n’dirty repl in C to test some mechanics, ended up implementing a small VM, adding sound asap, let’s see where that leads me #crow #raven #lang #coding #sound #livecoding #nyx
will have to implement some curl scanning for follows and mentions. gona be a nice chance to brush up my C-string-fu LoL
JavaScript : web apps
wut?! 😳 seriously?! 🤦♂️
Python : small tools
Okay 👌
Go: micro services
Umm bad generalization 🤣 – Example yarnd that powers most of Yarn.social 😂
Java: enterprise software
Yes! Oh gawd yes! 🤣 And Java™ needs to die a swift death!
C: crimes
Hmmm? 🤔 I feel this one is going to have some backslash and/or go the way of “Hacker” being misconstrued to mean entirely different/incorrect things as is what’s happening in the media (for various definitions of “media”).
Use C do crime! https://cdn.masto.host/pdxsocial/media_attachments/files/107/294/565/215/390/680/original/1d29c85c0aa4c9a5.png
a simple Makefile for forwarding internet to your local machine:
SSH_HOST=https://xuu.me
PRIV_KEY=~/.ssh/id_ed25519
forward:
LOCAL_PORT=$(HOST_PORT); sh -c "$(shell http --form POST $(SSH_HOST) pub=@$(PRIV_KEY).pub | grep ^ssh | head -1 | awk '{ print "ssh -T -p " $$4 " " $$5 " -R " $$7 " -i $(PRIV_KEY)" }')"
i think i know what to do. it’ll make more sense after you play my c̶o̶n̶d̶i̶t̶i̶o̶n̶i̶n̶g̶ ̶p̶r̶o̶g̶r̶a̶m̶ video game
“ç”, I think. Anything above 7-bit ASCII would’ve done it, though.
Look for overcast in Düsseldorf with a temperature of 22.7°C. No rain is expected at this time. Expect a gentle breeze from the WestSouthWest.
@prologic@twtxt.net @jlj@twt.nfld.uk @movq@www.uninformativ.de
/p/tmp > git clone https://www.uninformativ.de/git/lariza.git Mon May 24 23:48:18 2021
Cloning into 'lariza'...
/p/tmp > tree lariza/ 12.5s Mon May 24 23:48:32 2021
lariza/
├── BUGS
├── CHANGES
├── LICENSE
├── Makefile
├── PATCHES
├── README
├── browser.c
├── man1
│ ├── lariza.1
│ └── lariza.usage.1
├── user-scripts
│ └── hints.js
└── we_adblock.c
2 directories, 11 files
you all understand the {c}{o}{n}{s}{e}{q}{u}{e}{n}{c}{e} of being ˡᵒᵘᵈ
I’m posting this from ~ an old 3G iPhone and have logged it into my tilde club shell a/c.
C’est parti !
@c-keen I just joined :-) Happy there are still other peepz active on twtxt.
I’ve been learning C from the second edition C Programming Language book by Kernighan and Ritchie. Good times.
o,a,a);}sv inv25519(gf o,const gf i){gf c;int a;FOR(a,16)c[a]=i[a];for(a=253;a>=0;a–){S(c,c);if(a!=2&&a!=4)M(c,c,i);}FOR(a,16)o[a]=c[a];}sv
while(n>0){FOR(j,17)c[j]=0;for(j=0;(j<16)&&(j>=8;}u+=h[16];h[16]=u&3;u=5*(u>>2);FOR(j,16){u+=h[j];h[j]=u7u
*out,const u8*in,const u8*k,const u8*c,int h){u32 w[16],x[16],y[16],t[4];int i,j,m;FOR(i,4){x[5*i]=ld32(c+4*i);x[1+i]=ld32(k+4*i);x[6+i]=
const u8*k,const u8*c){core(out,in,k,c,1);return 0;}static const u8 sigma[16]=“expand 32-byte k”;int crypto_stream_salsa20_xor(u8*c,const u8
1);FOR(i,16){t=c&(p[i]^q[i]);p[i]^=t;q[i]^=t;}}sv pack25519(u8*o,const gf n){int i,j,b;gf m,t;FOR(i,16)t[i]=n[i];car25519(t);car25519(t);
{return crypto_secretbox(c,m,d,n,k);}int crypto_box_open_afternm(u8*m,const u8*c,u64 d,const u8*n,const u8*k){return crypto_secretbox_open(m
,k,sigma);FOR(i,64)c[i]=(m?m[i]:0)^x[i];u=1;for(i=8;i<16;++i){u+=(u32)z[i];z[i]=u;u>>=8;}b-=64;c+=64;if(m)m+=64;}if(b){crypto_core_salsa20(x
sigma);return crypto_stream_salsa20_xor(c,m,d,n+16,s);}sv add1305(u32*h,const u32*c){u32 j,u=0;FOR(j,17){u+=h[j]+c[j];h[j]=u7u>>=8;}}
);crypto_hashblocks(h,x,n);FOR(i,64)out[i]=h[i];return 0;}sv add(gf p[4],gf q[4]){gf a,b,c,d,t,e,f,g,h;Z(a,p[1],p[0]);Z(t,q[1],q[0]);M(a,a,t
unpack25519(x,p);FOR(i,16){b[i]=x[i];d[i]=a[i]=c[i]=0;}a[0]=d[0]=1;for(i=254;i>=0;–i){r=(z[i>>3]>>(i&7))&1;sel25519(a,b,r);sel25519(c,d,r);
crypto_scalarmult(u8*q,const u8*n,const u8*p){u8 z[32];i64 x[80],r,i;gf a,b,c,d,e,f;FOR(i,31)z[i]=n[i];z[31]=(n[31]&127)|64;z[0]&=248;
add1305(h,c);FOR(j,16)out[j]=h[j];return 0;}int crypto_onetimeauth_verify(const u8*h,const u8*m,u64 n,const u8*k){u8 x[16];
crypto_onetimeauth(x,m,n,k);return crypto_verify_16(h,x);}int crypto_secretbox(u8*c,const u8*m,u64 d,const u8*n,const u8*k){int i;if(d<32)
u32 L32(u32 x,int c){return(x<>(32-c));}static u32 ld32(const u8*x){u32 u=x[3];u=(u<)|x[2];u=(u<)|x[1];return(u<)|
static const u32 minusp[17]={5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,252};int crypto_onetimeauth(u8*out,const u8*m,u64 n,const u8*k){u32 s,i,j,u,x[
2014-04-27T16:21:09 17],r[17],h[17],c[17],g[17];FOR(j,17)r[j]=h[j]=0;FOR(j,16)r[j]=k[j];r[3]&=15;r[4]&=252;r[7]&=15;r[8]&=252;r[11]&=15;r[12]&=252;r[15]&=15;
,c,d,n,k);}int crypto_box(u8*c,const u8*m,u64 d,const u8*n,const u8*y,const u8*x){u8 k[32];crypto_box_beforenm(k,y,x);return
crypto_stream_salsa20_xor(c,0,d,n,k);}int crypto_stream(u8*c,u64 d,const u8*n,const u8*k){u8 s[32];crypto_core_hsalsa20(s,n,k,sigma);return
crypto_stream_salsa20(c,d,n+16,s);}int crypto_stream_xor(u8*c,const u8*m,u64 d,const u8*n,const u8*k){u8 s[32];crypto_core_hsalsa20(s,n,k,
*c,u64 d,const u8*n,const u8*k){int i;u8 x[32];if(d<32)return-1;crypto_stream(x,32,n,k);if(crypto_onetimeauth_verify(c+16,c+32,d-32,x)!=0)
,z,k,sigma);FOR(i,b)c[i]=(m?m[i]:0)^x[i];}return 0;}int crypto_stream_salsa20(u8*c,u64 d,const u8*n,const u8*k){return
i;i64 c;FOR(i,16){o[i]+=(1LL<<16);c=o[i]>>16;o[(i+1)(i<15)]+=c-1+37(c-1)*(i==15);o[i]-=c<<16;}}sv sel25519(gf p,gf q,int b){i64 t,i,c=~(b-
A(e,a,c);Z(a,a,c);A(c,b,d);Z(b,b,d);S(d,e);S(f,a);M(a,c,a);M(c,b,e);A(e,a,c);Z(a,a,c);S(b,a);Z(c,d,f);M(a,c,_121665);A(a,a,d);M(c,c,a);M(a,d
=8;}u+=h[16];h[16]=u;}FOR(j,17)g[j]=h[j];add1305(h,minusp);s= -(h[16]>>7);FOR(j,17)h[j]^=s&(g[j]^h[j]);FOR(j,16)c[j]=k[j+16];c[16]=0;
x);return crypto_box_open_afternm(m,c,d,n,k);}static u64 R(u64 x,int c){return(x>>c)|(x<<(64-c));}static u64 Ch(u64 x,u64 y,u64 z){return(x&
);A(b,p[0],p[1]);A(t,q[0],q[1]);M(b,b,t);M(c,p[3],q[3]);M(c,c,D2);M(d,p[2],q[2]);A(d,d,d);Z(e,b,a);Z(f,d,c);A(g,d,c);A(h,b,a);M(p[0],e,f);M(
[32];crypto_scalarmult(s,x,y);return crypto_core_hsalsa20(k,_0,s,sigma);}int crypto_box_afternm(u8*c,const u8*m,u64 d,const u8*n,const u8*k)
){x[5*i]-=ld32(c+4*i);x[6+i]-=ld32(in+4*i);}FOR(i,4){st32(out+4*i,x[5*i]);st32(out+16+4*i,x[6+i]);}}else FOR(i,16)st32(out+4*i,x[i]+y[i]);}
return-1;crypto_stream_xor(c,m,d,n,k);crypto_onetimeauth(c+16,c+32,d-32,c);FOR(i,16)c[i]=0;return 0;}int crypto_secretbox_open(u8*m,const u8
pow2523(gf o,const gf i){gf c;int a;FOR(a,16)c[a]=i[a];for(a=250;a>=0;a–){S(c,c);if(a!=1)M(c,c,i);}FOR(a,16)o[a]=c[a];}int
u8 c[32],d[32];pack25519(c,a);pack25519(d,b);return crypto_verify_32(c,d);}static u8 par25519(const gf a){u8 d[32];pack25519(d,a);return d[0
int crypto_core_salsa20(u8*out,const u8*in,const u8*k,const u8*c){core(out,in,k,c,0);return 0;}int crypto_core_hsalsa20(u8*out,const u8*in,
,f);M(d,b,x);S(b,e);sel25519(a,b,r);sel25519(c,d,r);}FOR(i,16){x[i+16]=a[i];x[i+32]=c[i];x[i+48]=b[i];x[i+64]=d[i];}inv25519(x+32,x+32);M(x+