diff --git a/2016_03_12_chan-chan-chan.md b/2016_03_12_chan-chan-chan.md index 53c73e7..1e21e2f 100644 --- a/2016_03_12_chan-chan-chan.md +++ b/2016_03_12_chan-chan-chan.md @@ -1,3 +1,5 @@ +# chan chan chan + Why channels of channels of channels can be useful? Why we often see statements like `make(chan chan chan int)` in Go code ? Let's look at example [here](https://rogpeppe.wordpress.com/2009/12/01/concurrent-idioms-1-broadcasting-values-in-go-with-linked-channels/) diff --git a/2016_05-29-contributing.md b/2016_05-29-contributing.md index 6db222a..58931f8 100644 --- a/2016_05-29-contributing.md +++ b/2016_05-29-contributing.md @@ -1,5 +1,5 @@ -Some possible contribution tasks +# Some possible contribution tasks 1. More substitutes for Future callback methods. (project = trackedfuture, level = easy) diff --git a/2016_27_03_back-my-stack-traces.md b/2016_27_03_back-my-stack-traces.md index 203d137..4735883 100644 --- a/2016_27_03_back-my-stack-traces.md +++ b/2016_27_03_back-my-stack-traces.md @@ -1,5 +1,5 @@ - +# Give my stacktraces back One of the annoying things when debugging concurrent Scala programs - is luck of stack traces from asynchronous calls with ```Future```s. Ie. when we span task and receive an exception from one, then it is impossible to find in the exception trace, diff --git a/_config.yml b/_config.yml deleted file mode 100644 index 1e33422..0000000 --- a/_config.yml +++ /dev/null @@ -1,17 +0,0 @@ -lsi: false -safe: true -source: ./ -incremental: false -highlighter: rouge -#theme: minima -gist: - noscript: false -kramdown: - math_engine: mathjax - syntax_highlighter: rouge -plugins: -- jekyll-feed -title: rssh notes -description: Random notes about programming -author: Ruslan Shevchenko - diff --git a/chan-chan-chan.md b/chan-chan-chan.md deleted file mode 100644 index 53c73e7..0000000 --- a/chan-chan-chan.md +++ /dev/null @@ -1,19 +0,0 @@ -Why channels of channels of channels can be useful? Why we often see statements like `make(chan chan chan int)` in Go code ? - -Let's look at example [here](https://rogpeppe.wordpress.com/2009/12/01/concurrent-idioms-1-broadcasting-values-in-go-with-linked-channels/) -or [scala version](https://github.com/rssh/scala-gopher/blob/master/src/test/scala/example/BroadcasterSuite.scala) - -Why type of `listenc` is `Channel[Channel[Channel[Message]]]` ? - -The answer is - exchanging information between goroutines in dynamic ways, like an emulation of -[asynchronous method calls](https://en.wikipedia.org/wiki/Asynchronous_method_invocation) between objects. - -Let we want to request information which must return to us some 'A'. -Instead calling `o.f(x)` and invocation of a method which will return `A` on the stack, we create a channel -(of type `Channel[A]`) and pass one to target goroutine via endpoint channel (which will have type `Channel[Channel[A]]`). -After this goroutine will retrieve `a` and send one back to the canal which was received from the endpoint. - -So, if we see in signature `Channel[Channel[A]]` this usually means "entry for information request about 'A'". - ------------------------ -[index](https://github.com/rssh/notes) diff --git a/scripts/generate-feed.sc b/scripts/generate-feed.sc new file mode 100755 index 0000000..6e7fa29 --- /dev/null +++ b/scripts/generate-feed.sc @@ -0,0 +1,70 @@ +#!/usr/bin/env -S scala-cli -S 3 + +//> using scala "3.2.1" +//> using dep "com.mchange::audiofluidity-rss:0.0.6" +//> using dep "com.lihaoyi::os-lib::0.9.3" +// + +val blogTitle = "Random notes about programming" +val author = "Ruslan Shevchenko " +val baseUrl = "https://github.com/rssh/notes" +val feedUrl = "https://rssh.github.io/notes/feed.xml" +val wd = os.pwd +val path = if wd.toString.endsWith("scripts") && os.exists(wd / "generate-feed.sc") then + os.Path(wd.wrapped.getParent) + else if os.exists(wd/"scripts"/"generate-feed.sc") then + wd + else + println(s"Can't determinate directory: should be scripts or current dirrectory, not in ${wd}, exiting") + System.exit(1) + ??? + +import audiofluidity.rss.* +import java.time.* + +def extractTitle(lines:IndexedSeq[String]): Option[String] = { + val titleLine = "^title: (.*)$".r + val head1Line = """^\# (.*)$""".r + val head2Line = """^\#\# (.*)$""".r + lines.collectFirst{ + case titleLine(title) => title + case head1Line(title) => title + case head2Line(title) => title + } + +} + +println(s"path=$path") +val items = os.list(path).filter(file => + os.isFile(file) && file.ext == "md" && + file.baseName != "README" + ).flatMap{ file => + val dateRegExpr = """([0-9]+)_([0-9]+)_([0-9]+)_(.*)$""".r + file.baseName.toString match + case dateRegExpr(sYear,sMonth,sDay, rest) => + val (month, day) = if (sMonth.toInt > 12) { + (sDay.toInt, sMonth.toInt) + } else (sMonth.toInt, sDay.toInt) + val year = sYear.toInt + val date = LocalDate.of(year,month,day) + println(s"file=$file, date=$date") + Some((file, date)) + case _ => + println(s"file $file without date prefix, skipping") + None + }.sortBy(_._2).reverse.map{ (file, ctime) => + val mdContent = os.read.lines(file) + val title = extractTitle(mdContent).getOrElse(file.toString) + val pubDate = ZonedDateTime.of(ctime, LocalTime.MIN, ZoneId.systemDefault) + Element.Item.create(title, s"${baseUrl}/file", "at {}", author, pubDate=Some(pubDate)) + } + +val channel = Element.Channel.create(blogTitle,feedUrl,"random unsorted notes",items) +println(Element.Rss(channel).asXmlText) +val rss = Element.Rss(channel).asXmlText +val targetDir = path/"_site" +if (!os.exists(targetDir)) { + os.makeDir(targetDir) +} +os.write.over(targetDir/"feed.xml",rss) +