Category Archives: Coding

New React Context API

I like new react API for creating and using context. It feels right. One thing I immediately tried to do was creating a helper which simplifies consuming multiple contexts. Because they create context hell. When you component uses more than one context and because of a children as a function pattern (which is basically the same as render props pattern where component’s children function is specified as a component’s prop named render), code gets familiar indent to the left (callback hell).

For example with the use of this helper,

<Theme.Consumer>
    { theme => (
        <Language.Consumer>
            { language => (
                <App theme={theme} language={language} />
            )}
        </Language.Consumer>    
    )}
</Theme.Consumer>

would become

<Consume contexts={[Theme, Language]}>
    { (theme, language) => (
        <App theme={theme} language={language} />
    )}  
</Consume>

But after giving it a second thought, I realized in high-performance web applications this “multiple contexts consumer” case scenario can be a bad idea in most cases. Because If we have for example two contexts that are always used together, it’s better to just have one context anyway. But if a component uses more contexts which aren’t co-dependent, that means parts of component will be re-rendered unnecessary. So the component should be split into components which uses only one context or co-dependant contexts.

If you are interested in Consumer component, you can see it in following snippet with example usage. I’ve also added Provide component which mirrors Consume component for the sake of completeness. It’s no problem though if you specify Providers separately or not at all – in that case it will use context’s default value than).

Goroutines don’t panic if channel they write to is gone

Couple of months ago I wrote an article about error handling in concurrent Go programs. One concern I had about it was if other goroutines would panic if some goroutine produces an error value which causes return from function when the channel is iterated with range construct.

So I made another program that mimics scenario. It spawns couple of goroutines, each taking a second more to complete than previous (for the sake of test being easier to observe). When done, they write to channel. 5th goroutine returns an error (after 5 seconds) via channel which is iterated using range. In case of an error, it’s returned from function.

package main

import (
    "errors"
    "sync"
    "time"
)

type data struct {
    err  error
    data int
}

func someWork(dataChan chan<- *data, collection []int) {
    var wg sync.WaitGroup
    l := len(collection)
    wg.Add(l)
    for i, e := range collection {
        go func(i, e int) {
            time.Sleep(time.Duration(i) * time.Second)
            var err error
            if i == 5 {
                err = errors.New("error")
            }
            dataChan <- &data{err, e}
            defer wg.Done()
        }(i, e)
    }
    wg.Wait()
    close(dataChan)
}

func someFunc() {
    collection := []int{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
    dataChan := make(chan *data)

    go someWork(dataChan, collection)

    for c := range dataChan {
        if c.err != nil {
            return
        }
    }

    time.Sleep(2 * time.Second)
}

func main() {
    someFunc()
    time.Sleep(20 * time.Second)
}

It surprised me a little other goroutines which still aren't finished don't cause panic because channel is gone even. For more realistic test I've also added some work after someFunc is finished.

Don't know why, it sure has to do with the way garbage collection works in Go (would be a great read if there's detailed explanation of it). I'm glad though I don't have to deal with goroutines panicking myself.

One thing I didn't do in example is cancelling the work running goroutines are still doing so they stop wasting additional memory. One idiomatic way to do that is with the use of context package from standard library, which provides cancellation and timeout mechanisms.

My experiences using Anko library (Android Kotlin)

I’ve been using Anko library from the start of my Kotlin journey and my experiences with it are mostly positive.

According to its Github readme page, Anko is

...a Kotlin library which makes Android application development faster and easier. It makes your code clean and easy to read, and lets you forget about rough edges of the Android SDK for Java.

Anko consists of several parts:

- Anko Commons: a lightweight library full of helpers for intents, dialogs, logging and so on;
- Anko Layouts: a fast and type-safe way to write dynamic Android layouts;
- Anko SQLite: a query DSL and parser collection for Android SQLite;
- Anko Coroutines: utilities based on the kotlinx.coroutines library.

It provides basic guide for getting started.

Where I find Anko the most valuable is when dealing with SQLite and creating dialogs.

  • When dealing with SQLite, you don’t need to worry about closing the database after querying it, concurrent access, creating cursors.
  • Dialogs simplifies Android development so much because it eliminates all boilerplate associated with connecting dialog fragment to activity and dialog-activity communication with after user interacted with the dialog.

I don’t like its layouts component though. Because:

  • it encourage mixing logic with presentation,
  • it doesn’t work so nicely with complex layouts,
  • it has no layout preview.

But because pros of using the library out-weights the cons, I’m willing to rate my experience with the library positively. I haven’t refrained from using its layouts component, just limited its usage to simple use cases.

Error handling in concurrent programs in Golang

Error handling in concurrent programs in Go consists of little more work than

if err != nil {
   return err
}

because the return value doesn’t reach intended receiver (for example in parent function where function was fired as a goroutine using go keyword). Just as we use channel for sending resulting data, we must also use channel for sending error. And we can do this using single channel of type Data which is a struct that will hold data and error for the data. And than when we range over channel we first check if there’s an error (and when we are done, when all tasks have been completed, we close the channel).

Using same channel for data and error simplifies concurrency, we don’t have to handle scenarios of completed tasks end error handling separately.

So here’s a simple example of what I have in mind (with sending HTTP request as a concurrent task).

type Data struct {
    URL      string
    IsAvailable bool
    Err      error
}

func getAvailableSites(urls []string) ([]string, error) {
    var wg sync.WaitGroup
    urlChan := make(chan *Data)

    go func() {
        wg.Wait()
        close(urlChan)
    }()

    for _, url := range urls {
        go checkIfSiteAvailable(&wg, urlChan, url)
    }

    availableSites := []string{}
    for data := range urlChan {
        if data.Err != nil {
            return nil, fmt.Errorf("problem getting url: %v", data.Err)
        }
        if (data.IsAvailable) {
            availableSites = append(availableSites, data.URL)
        }
    }
    return availableSites, nil
}

func checkIfSiteAvailable(wg *sync.WaitGroup, urlChan chan<- *Data, url string) {
    defer wg.Done()

    resp, err := http.Head(url)
    if err != nil {
        urlChan <- &Data{Err: err}
        return
    }

    if resp.StatusCode != http.StatusOK {
        urlChan <- &Data{Err: fmt.Errorf("status code not OK for %s", url)}
        return
    }

    urlChan <- &Data{URL: url, Available: true}
}

I won’t be describing logic here just a steps related to concurrency and error handling in it. In getAvailableSites we

  • set up a channel we’ll be using for sending the data for specific URL (with error as part of data),
  • a WaitGroup to specify how many goroutines we’ll fire and after all finish, Go will know to close channel,
  • define and fire a goroutine which waits for all goroutines to finish and than close a channel,
  • for each URL we call a function checkIfSiteAvailable as a goroutine (alonside URL we pass channel so we can send resulting data to it and a WaitGroup to be able to indicate task is finished)
  • iterate over a channel, which will finish after we close the channel (from 3rd point). Iterating over a channel is a blocking operation so we don’t have to worry data from channel will get lost. In for loop we check for error and return it as if no concurrency was involved.

In checkIfSiteAvailable we defer call to wg.Done to indicate task is finished. And whenever there’s an error we send instance of Data with only Err field specified because in this simple example we don’t need other fields. Lastly, we send the actual data (wrapped in the Data struct).

Libraries over frameworks

Lately (in term of years) I noticed I prefer using libraries over frameworks. Or in other words I like to use packages that each do their one thing well rather than one package with all batteries included. I recognize both libraries and frameworks have their pros and cons.

You can see my preference for libraries if you are reading my blog where I write a lot about web development, specifically about React and Go. Well, Go is a programming language but because it has an excellent standard library, there’s actually no need for a framework.

The most obvious advantage of using libraries over frameworks I have are:

  • I have a freedom of putting all pieces of an application as I see fit and only those necessarily.
  • I can easily replace one piece after another, better option appears.
  • they take less time to learn.
  • feeling I have a control over them not other way around.
  • process of updating a library is less painful.

The biggest pain point is writing boilerplate after starting every new project. But this is solvable by maintaining your own starter/base/boilerplate. I don’t like using boilerplates from other people because they don’t fit my mental model (but that doesn’t mean I don’t like inspecting them for fresh ideas on how to I improve my own boilerplate).

Disadvantages of using frameworks I’ve experienced so far are:

  • hard to learn
  • developing in it I often don’t feel like a [insert a programming language] developer
  • learning specifics which are in general useless instead of core programming concepts, computer science that can be reapplied to every new project.
  • using only small subset of features or fixing a bug? Too bad, you have to learn all of it so that you might not break anything.
  • having to conform to specific mindset and way of doing things because framework is designed for doing things THAT way (convention over configuration).

I only enjoyed using/learning frameworks at the beginning of my career because I didn’t exactly know what a modern applications consist of. After years of learning how to architecture an application (folder structure, design patterns etc) on my own or from popular frameworks I became confident in doing them from scratch with the help of libraries that aren’t limiting my creativeness.