Edge detection-based ASCII art generator
Materials for my QCon NYC 2016 talk: "Beyond Breakpoints: A Tour Of Dynamic Analysis"
dijkstracula/Advent-Of-Code-2017 3
advent of code 2017 solutions in standard ml
dijkstracula/Bandwortersplitter 1
Compound German word splitter
things 2 eat
German flash card generator
Clojure workshop
dijkstracula/cmpt220f2020lab4 0
Sample repository for CMPT 220 Lab 4, Winter 2020
A commute planner.
pull request commentstellentus/go-plc
tag parser: trim "Program:" prefix
The PR is much less elegant now. 😢 😆
But I figured that would be the way to solve it.
comment created time in an hour
delete branch stellentus/go-plc
delete branch : nathan/tag_parser_trim_prefix
delete time in an hour
push eventstellentus/go-plc
commit sha 30c06641bfe9bd3afbef38436a74b6448916bb71
tag parser: trim "Program:" prefix Technically, the colon in "Program:" causes the tag parser to fail since it's an invalid character. Special-case the parser to drop this prefix if it's present.
push time in an hour
PR merged stellentus/go-plc
Technically, the colon in "Program:" causes the tag parser to fail since it's an invalid character. Special-case the parser to drop this prefix if it's present.
pr closed time in an hour
push eventstellentus/go-plc
commit sha 285619667e7926e869e052234ff5d7fe51957793
Add arrays to Splitter.ReadTag
commit sha 414345d51d05627eeea00d8c68d5430e1b057451
Add arrays to Splitter.WriteTag
commit sha e1ca59ac301f3c9b65d6199f87a6891c83c93f5c
Split common code into a function
commit sha 7dbc06a1f15c77d2d7fa5d63e65a3f942db45ce3
Stop prepending empty struct prefix
commit sha 149b177bd14eef9dddd73457e8d96b30c3f06a7c
Simplify error handling
commit sha c80b17c951fa5bee498ed00379269fb156e84fc7
Merge branch 'array-splitter' Close #22
push time in an hour
PR closed stellentus/go-plc
This does 2 things:
- Add support for arrays
- Add support for top-level structs (i.e. with a tag name of
""
)
pr closed time in an hour
push eventstellentus/go-plc
commit sha df6323ace7400ef3002983ec70e58b1b08d4401b
Simplify error handling
push time in an hour
Pull request review commentstellentus/go-plc
func (r SplitReader) ReadTag(name string, value interface{}) error { return err } +func (r SplitReader) readValue(name string, val reflect.Value) error {+ if !val.CanAddr() {+ return fmt.Errorf("Cannot address %s", name)+ }++ valPointer := val.Addr().Interface()+ if val.Kind() == reflect.Ptr {+ // Since val actually is a pointer, we want its value instead.+ if val.IsNil() {+ // It's currently a nil pointer, so we need to allocate and set the value+ newVal := reflect.New(val.Type().Elem())
Immediately after I use reflect
, I forget how it works. 😆
Short answer: approximately yes.
Medium answer: in this case, val.Type()
is *someType
, so we need val.Type.Elem()
to get someType
, and that's what we allocate.
Long answer:
The point of this code is to allow a user to have a pointer-to-value in their struct and we'll fill that. Otherwise they'd have to pre-allocate all of their pointers before calling this code, which is just irritating.
The input to readValue
is a struct field. (Note it's the reflect.Value
for the field, not a pointer to the field). If it turns out that field is a pointer and it's nil
, then I get the reflect.Type
of the thing we want to point to, and reflect.New
allocates a new one. We then set the struct's field pointer to use that value, which gets filled in a normal call to ReadTag
.
comment created time in an hour
Pull request review commentstellentus/go-plc
func (sw SplitWriter) WriteTag(name string, value interface{}) error { if !ok { continue // Can't touch that }- fieldName = name + "." + fieldName // add prefix+ if name != "" {
This came up because I needed it (and it works).
Imagine I want to read these top-level tags:
MY_TAG
ANOTHER_TAG
I define a struct: type struct AllTags {MY_TAG, ANOTHER_TAG float32}
Then I read it: device.ReadTag("", &allTags)
...I think it's ok if the Locker
doesn't handle this case because I think locking will occur below the Splitter
.
comment created time in 2 hours
Pull request review commentstellentus/go-plc
func (r SplitReader) ReadTag(name string, value interface{}) error { if !ok { continue // Can't touch that }- fieldName = name + "." + fieldName // add prefix+ if name != "" {+ fieldName = name + "." + fieldName // add prefix+ } field := str.Field(i)- if !field.CanAddr() {- err = fmt.Errorf("Cannot address %s", fieldName)+ err = r.readValue(fieldName, field)
I'm inconsistent about using it.
But in this case I think there's good reason to avoid it (maybe?).
That idiom is usually used when the returned variable is only locally scoped (e.g. when the error is immediately returned, or a value is used in the block). So the idiom is usually :=
.
In this case the err
is used later, so while the idiom would still work, I think it might deceive the reader. The err
was used later because at one point I had some code that executed after the switch. (Or at least intended to move in that direction.)
... however, now that the code is effectively break; return err
in those cases, I think the idiom would be more readable here. So good point: I'll refactor this a bit to return instead of break, using the idiom.
comment created time in 2 hours
startedeliddell1/RollJam
started time in 5 hours
startedolegv142/CC1101
started time in 5 hours
startedgrspy/rcswitch-cc1101
started time in 5 hours
startedn8ohu/CC1101-FSK
started time in 5 hours
issue closedstellentus/go-plc
Return named error types from ReadTag and WriteTag
It would be nice to be able to distinguish between errors writing to the PLC and errors in the provided tag/value. Then users know whether the error was in their request, or in the network.
closed time in 6 hours
stellentuspull request commentstellentus/go-plc
tag parser: trim "Program:" prefix
I think one of your test cases is (slightly) wrong.
{"Program:Field.Array[42].Member[16]", []string{"Field", "Array", "42", "Member", "16"}, ""},
I think the first returned string should be Program:Field
, not just Field
. I believe it would be possible for there to be a top-level tag Field
as well as a program named "Field" (with a corresponding tag name Program:Field
). In that situation, I believe the tag locker would have a minor bug: those two tags would share a lock. (Likely safe with a minor performance impact.)
In our use case, this is not a problem (since none of our program names overlap with a top-level tag name), so I'm fine with approving this PR for now. But it should probably be fixed, just in case.
If this is a small change you can do within the week, I'll wait for it. Otherwise, I'll go ahead and merge the PR later this week.
comment created time in 6 hours
push eventstellentus/go-plc
commit sha 05474d8cff00f85df039db6975b22d932b504418
TagLocker ReadWriter impl This patch includes an implementation of a plc.ReadWriter that gates access on a downstream ReadWriter through intention locking on each of the given tag name's components. The benchmark results for this implementation follow: BenchmarkSerialTagLocking BenchmarkSerialTagLocking-12 292084 4155 ns/op BenchmarkLowConcurrencyTagLocking BenchmarkLowConcurrencyTagLocking-12 1337608 916 ns/op BenchmarkMedConcurrencyTagLocking BenchmarkMedConcurrencyTagLocking-12 1889516 657 ns/op BenchmarkHighConcurrencyTagLocking BenchmarkHighConcurrencyTagLocking-12 1850548 651 ns/op BenchmarkSerialTagLockingWithHeavyWrites BenchmarkSerialTagLockingWithHeavyWrites-12 271552 3702 ns/op BenchmarkLowConcurrencyTagLockingWithHeavyWrites BenchmarkLowConcurrencyTagLockingWithHeavyWrites-12 1304198 1064 ns/op BenchmarkMedConcurrencyTagLockingWithHeavyWrites BenchmarkMedConcurrencyTagLockingWithHeavyWrites-12 1655668 723 ns/op BenchmarkHighConcurrencyTagLockingWithHeavyWrites BenchmarkHighConcurrencyTagLockingWithHeavyWrites-12 1753326 751 ns/op PASS As expected, throughput increases when we add a degree of concurrency, but it seems to level out pretty quickly. Unsurprisingly, as well, the intention write locks seem to decrease throughput slightly as readers will be unable to grab intention read locks on interior nodes until those operations complete.
push time in 7 hours
PR merged stellentus/go-plc
TagLocker ReadWriter impl
This patch includes an implementation of a plc.ReadWriter that
gates access on a downstream ReadWriter through intention locking
on each of the given tag name's components.
The benchmark results for this implementation follow:
BenchmarkSerialTagLocking
BenchmarkSerialTagLocking-12 292084 4155 ns/op
BenchmarkLowConcurrencyTagLocking
BenchmarkLowConcurrencyTagLocking-12 1337608 916 ns/op
BenchmarkMedConcurrencyTagLocking
BenchmarkMedConcurrencyTagLocking-12 1889516 657 ns/op
BenchmarkHighConcurrencyTagLocking
BenchmarkHighConcurrencyTagLocking-12 1850548 651 ns/op
BenchmarkSerialTagLockingWithHeavyWrites
BenchmarkSerialTagLockingWithHeavyWrites-12 271552 3702 ns/op
BenchmarkLowConcurrencyTagLockingWithHeavyWrites
BenchmarkLowConcurrencyTagLockingWithHeavyWrites-12 1304198 1064 ns/op
BenchmarkMedConcurrencyTagLockingWithHeavyWrites
BenchmarkMedConcurrencyTagLockingWithHeavyWrites-12 1655668 723 ns/op
BenchmarkHighConcurrencyTagLockingWithHeavyWrites
BenchmarkHighConcurrencyTagLockingWithHeavyWrites-12 1753326 751 ns/op
PASS
As expected, throughput increases when we add a degree of concurrency, but it
seems to level out pretty quickly. Unsurprisingly, as well, the intention
write locks seem to decrease throughput slightly as readers will be unable
to grab intention read locks on interior nodes until those operations complete.
pr closed time in 7 hours
startedSuperMaZingCoder/TableIt
started time in 10 hours
startedastanin/python-tabulate
started time in 10 hours
startedjtdx-project/jtdx
started time in a day
pull request commentstellentus/go-plc
Note this is just one commit on top of #21 and #22.
comment created time in 2 days
PR opened stellentus/go-plc
It turns out I was using a different prefix in different places (plc
and plctag
). Now it's a const
.
pr created time in 2 days
pull request commentstellentus/go-plc
Generate a go struct from L5X tags
It turns out the real L5X had some more extra features. I've now added them and the L5X loads in its entirety.
In order to push that branch for review (on the private repo), this PR and #22 have to be merged.
comment created time in 2 days
PR opened stellentus/go-plc
This does 2 things:
- Add support for arrays
- Add support for top-level structs (i.e. with a tag name of
""
)
pr created time in 2 days
push eventstellentus/go-plc
commit sha 8f45e7ed11df481b5c5caba5a633f478bc0a0367
Improve output for StringFamily
commit sha e15db07062a4ae6fa5c0ec88eef01b488c7451f3
Add support for BOOL arrays
commit sha 6b2378c86253fc67b0465c266cd6e48b09cd3e1a
Merge branch 'array-splitter' into james/testing-get-all-tags
commit sha 8b101921c929cfdd8aa67a237e392674ca94d094
Fix struct tag prefix
push time in 2 days