-
-
Notifications
You must be signed in to change notification settings - Fork 654
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add channels concept #2324
Add channels concept #2324
Conversation
Dear RezaSiThank you for contributing to the Go track on Exercism! 💙
Dear Reviewer/Maintainer
Automated comment created by PR Commenter 🤖. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The content you present here seems to be copied from https://www.golangbootcamp.com/book/concurrency. The book does not have any license file so we cannot know if the author allows copying without attribution. GoBootcamp/book#48 This is too risky for us.
The content needs to written in your own words, copied from places that explicitly allow copying without attribution (e.g. via an MIT license) or the sentences that are copied need to be quoted and the source needs to be added as a footnote (this is legally only allowed for short sections if not explicitly permitted otherwise).
I only looked at the first part so far. I don't know for how much of the total content this applies to. It's easier for you to know. In any case, please rework all the copied content so it follows the rules above. If you have any questions, let me know.
Did you invent the exercise from scratch? If yes, I could start reviewing that part. |
Yes, some part of the intro and about is copied from this site and golang tut, I don't know this, but it's ok, I will try to write it again with my words! |
Yes, it's not copied from somewhere or another exercise, tnx for the review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had a look at the about.md file. I will check out the exercise later on.
concepts/channels/.meta/config.json
Outdated
{ | ||
"blurb": "Channels are the pipes that connect concurrent goroutines.", | ||
"authors": ["RezaSi"], | ||
"contributors": ["RezaSi"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You only need to add yourself as author. A contributor is someone who makes small adjustments later on (or the reviewer if you think they had substantial impact on the result).
@@ -0,0 +1,115 @@ | |||
# About |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please ensure some general points are taken care of throughout the content:
- One line per sentence. (see https://exercism.org/docs/building/markdown/markdown#h-one-sentence-per-line)
- "golang" should be "Go". (see https://go.dev/doc/faq#go_or_golang)
- Make sure sentences start with a capital letter.
- If your text contains some inline code (even if it is just one work like "make"), that bit needs to be wrapped in backticks for better readability, see https://exercism.org/docs/building/markdown/markdown#h-code.
- If you can, please double check the grammar. If you are not a native speaker and have no one to help you with this, I will do the corrections later on before I merge the code.
concepts/channels/about.md
Outdated
@@ -0,0 +1,115 @@ | |||
# About | |||
|
|||
As you know, goroutines are a way to execute concurrent code in golang. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Remove "as you know". It might be a long time since the student did that exercise and they might have forgotten.
- On the word "goroutines" add a link to some document that explains goroutines. This helps students that forgot about them and it helps everyone as long as we don't have the goroutines concept on Exercism yet. Potential link: https://go.dev/tour/concurrency/1
concepts/channels/about.md
Outdated
value := <-ch // Receive from ch, and assign value to value variable. | ||
``` | ||
|
||
Create a new channel with make(chan val-type). Channels are typed by the values they convey. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would recommend to first show how to create a channel and then how to send/receive data. That makes it easier to understand the comments you have above.
concepts/channels/about.md
Outdated
channel := make(chan bool) | ||
go exist(slice[:len(slice)/2], lookForValue, channel) | ||
go exist(slice[len(slice)/2:], lookForValue, channel) | ||
x, y := <-channel, <-channel // receive from channel |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
x, y := <-channel, <-channel // receive from channel | |
x, y := <-channel, <-channel // receive 2 values from channel |
concepts/channels/about.md
Outdated
slice := []int{1, 7, 8, -9, 12, -1, 13, -7} | ||
lookForValue := 8 | ||
|
||
channel := make(chan bool) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
results
or resultCh
might be a better name here
concepts/channels/about.md
Outdated
### Notes: | ||
- Only the sender should close a channel, never the receiver. Sending on a closed channel will cause a panic. | ||
|
||
- Channels aren't like files; you don't usually need to close them. Closing is only necessary when the receiver must be told there are no more values coming, such as to terminate a range loop. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to be a quote from Tour of Go and should be marked as such. You can quote with ">" in markdown and you can use a footnote to state the source. Their license only allows to use the material if you set the same license for the derived content which we don't have at the moment.
As discussed before, this applies to all the content in the PR. Please either write things yourself or quote with source. I am sorry but if your don't stick to those legal rules, I will be forced to reject the PR.
The rules also apply to code examples btw.
@junedev Tnx for all your advice, I think resolved all, and repair some other parts. |
03a8465
to
4649624
Compare
@junedev Any update? |
@RezaSi Sorry for the wait. I had to discuss with the Exercism leadership how to proceed with this PR. The problem is that the concept content still contains some sentences that are copied without attribution and some others were there were only slight changes made to the original content. This happened after I mentioned the issue twice already. It is too risky for us to merge content like this and it takes too much time for me to check and discuss every sentence. I will still consider the exercise part (without introduction.md) for merging but before I merge, I will remove the concept content from the PR and set the exercise status to "work in progress". Then there will be a follow up issue about writing the concept from scratch and once someone else worked on this, the exercise can go live. Hopefully, I can find some time to review the exercise on the weekend but I can't promise. I'm sorry this all takes so long but keep in mind that all track maintainers on Exercism are volunteers that do this work in their free time. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned before, I reviewed the exercise. I like the general idea about fetching data concurrently. I did not review the test file yet as it might change as you make some other adjustments. I will take a closer look once the other comments are addressed.
"for-loops", | ||
"range-iteration" | ||
], | ||
"status": "beta" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed, please change the status to "wip" for now.
@@ -0,0 +1,33 @@ | |||
# Instructions | |||
|
|||
In this exercise you'll be writing code to handle multilayer cache with Go channels. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When you say "multilayer cache", I imagine something like what is usually called "multi-level cache" which would mean you would check different cache levels in a fixed order and the deeper in the level you go the longer it takes to retrieve the data. The issue is that in such a scenario, you would always make the request sequentially and only proceed to the next level/layer when no result was returned. The word "layer" puts emphasis on this, layers are usually passed/pealed one by one. It might be less confusing to only say there are multiple caches available or talk about a cluster of caches (although the later also has its existing meaning which is different from the what you want to do in the exercise).
In any case, add one or two more sentences explaining what you mean by whatever term you decide to use to avoid misunderstandings.
type Cache struct { | ||
ResponseTime time.Duration | ||
Data map[string]string | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was wondering why this is presented in the instructions. It feels like this an implementation detail of the tests and it would be enough if the instructions would only state what the cache interface looks like (has a Get and Set method). Then the tests can provide whatever implementation for that interface. The internals of the cache should not matter for solving the exercise. You only need to say something like "some caches are faster to respond than others".
Showing this cache structs might make the student think they can solve the exercise by simply checking the value of "ResponseTime".
|
||
|
||
```go | ||
GetValueFromFastestLayer(cacheLayers []Cache, key string) (string, error) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code here should not present the function signature, instead if should show an example of how the function is called/used (and a potential result). You don't have to include the definition of the cache structs in here though.
Same for the other code block below.
|
||
## 2. Set value to all layers | ||
The key and value are given to you as `key` and `value` parameters. | ||
You have to set the value to all `cacheLayers` as fast as possible, you have maximum `max(cacheLayers.ResponseTime)` to set the value to all layers. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm struggling with this sentence as using the channels will have some overhead so you won't exactly hit the max response time. Maybe you can rephrase it a bit to say something like "Try to get as close as possible to the response time of the slowest cache."
ch := make(chan string, len(cacheLayers)) | ||
for _, cache := range cacheLayers { | ||
go func(cache Cache) { | ||
value, _ := cache.Get(key) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Get function should either not have an error return value or the error should be checked an if it is not nil, no value or an empty string should be send over the channel. It is good practice not to trust the result value in case the error is not nil.
func SetValueToAllLayers(cacheLayers []Cache, key string, value string) error { | ||
ch := make(chan error, len(cacheLayers)) | ||
for _, cache := range cacheLayers { | ||
go func(cache Cache) { | ||
err := cache.Set(key, value) | ||
ch <- err | ||
}(cache) | ||
} | ||
|
||
for range cacheLayers { | ||
<-ch | ||
} | ||
|
||
return nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple of thoughts about this task (and the solution):
- Currently, the function always returns nil so it could also just not have a return value at all.
- The instructions should clarify what happens in case Set returns an error.
- Overall, the required solution here is very similar to the one of the first task. Usually we try to bring up some new aspect in each task. Have another look at the learning objectives, maybe the task can be adjusted/re-written to cover something different. For example, currently your tasks don't cover ranging over a channel at all.
@@ -0,0 +1,9 @@ | |||
package cache | |||
|
|||
func GetValueFromFastestLayer(cacheLayers []Cache, key string) (value string, err error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove the names from the return values. Those should only be used when really needed as they can lead to mistakes easily.
@@ -0,0 +1,31 @@ | |||
package cache |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you follow the suggestion mentioned above with the interface, the cache implementation can be part of the standard test file. If you want to keep it as a separate file, you can list it in the config under the "editor" key so it shows up when solving the exercise but cannot be edited on the website.
@@ -0,0 +1,31 @@ | |||
package cache |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of "cache_struct.go", "types.go" is a more common name for a file like this.
Hello contributor and thank you for your contribution! |
Closing this as it seems abandoned. |
for this #2182