FAQ
Hi fellow Gophers,

I'm writing software to control my new network attached lamp (you'll
definitely get to see a video when it's done :-)).
At the moment I'm in the process of developing an architecture for effects
on a lamp e.g. a fire animation.
Each effect runs in it's own Goroutine and controls a single lamp. Effects
lifecycle is handled by launchpad.net/tomb
so that I can kill an effect at any time. Then there is a channel to send
it a new configuration while it's running e.g. to
change the colors of the fire.
I've got the following code and because the config is changed I already
added locking there, I'm unsure about
the functions returning the tomb and the channel though. They are never
changed so my gut feeling says the functions are fine.
However gut feeling and data races often don't work. So here is the code:
http://pastebin.com/M0ZtCKf5
Apply() is normaly run in it's own Goroutine so ConfigChan(), Tomb() and
Config() are called from other Goroutines

Greetings Niklas

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Search Discussions

  • Kyle Lemons at Feb 16, 2013 at 12:15 am
    a few comments:
    1) Use defer with locking:
    x.Lock()
    defer x.Unlock()
    return x.Y

    2) There's no real point to make an accessor for a control channel. Make
    it an exported field.
    3) Tomb is overkill for this. Kill the goroutine by closing its control
    channel.
    4) I would make an interface for the configs so you don't have to enumerate
    them in the controller code... untested and not completely thought out:
    http://play.golang.org/p/O1oEPcdob5


    On Fri, Feb 15, 2013 at 2:42 PM, Niklas Schnelle
    wrote:
    Hi fellow Gophers,

    I'm writing software to control my new network attached lamp (you'll
    definitely get to see a video when it's done :-)).
    At the moment I'm in the process of developing an architecture for effects
    on a lamp e.g. a fire animation.
    Each effect runs in it's own Goroutine and controls a single lamp. Effects
    lifecycle is handled by launchpad.net/tomb
    so that I can kill an effect at any time. Then there is a channel to send
    it a new configuration while it's running e.g. to
    change the colors of the fire.
    I've got the following code and because the config is changed I already
    added locking there, I'm unsure about
    the functions returning the tomb and the channel though. They are never
    changed so my gut feeling says the functions are fine.
    However gut feeling and data races often don't work. So here is the code:
    http://pastebin.com/M0ZtCKf5
    Apply() is normaly run in it's own Goroutine so ConfigChan(), Tomb() and
    Config() are called from other Goroutines

    Greetings Niklas

    --
    You received this message because you are subscribed to the Google Groups
    "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an
    email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Kyle Lemons at Feb 16, 2013 at 12:17 am
    oops, forgot the setup call:
    http://play.golang.org/p/ulmfx8Z4OY

    you'll notice that this abstracts away the basic behavior that the
    controller needs to manage: all it needs to do is have a config and control
    updates to the lamp's colors on a periodic basis.

    On Fri, Feb 15, 2013 at 4:15 PM, Kyle Lemons wrote:

    a few comments:
    1) Use defer with locking:
    x.Lock()
    defer x.Unlock()
    return x.Y

    2) There's no real point to make an accessor for a control channel. Make
    it an exported field.
    3) Tomb is overkill for this. Kill the goroutine by closing its control
    channel.
    4) I would make an interface for the configs so you don't have to
    enumerate them in the controller code... untested and not completely
    thought out:
    http://play.golang.org/p/O1oEPcdob5


    On Fri, Feb 15, 2013 at 2:42 PM, Niklas Schnelle <
    niklas.schnelle@gmail.com> wrote:
    Hi fellow Gophers,

    I'm writing software to control my new network attached lamp (you'll
    definitely get to see a video when it's done :-)).
    At the moment I'm in the process of developing an architecture for
    effects on a lamp e.g. a fire animation.
    Each effect runs in it's own Goroutine and controls a single lamp.
    Effects lifecycle is handled by launchpad.net/tomb
    so that I can kill an effect at any time. Then there is a channel to send
    it a new configuration while it's running e.g. to
    change the colors of the fire.
    I've got the following code and because the config is changed I already
    added locking there, I'm unsure about
    the functions returning the tomb and the channel though. They are never
    changed so my gut feeling says the functions are fine.
    However gut feeling and data races often don't work. So here is the code:
    http://pastebin.com/M0ZtCKf5
    Apply() is normaly run in it's own Goroutine so ConfigChan(), Tomb() and
    Config() are called from other Goroutines

    Greetings Niklas

    --
    You received this message because you are subscribed to the Google Groups
    "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an
    email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Niklas Schnelle at Feb 16, 2013 at 12:34 am
    Well I want FireEffect to implement an Effect interface like so
    type Effect interface {
    Config() interface{}
    ConfigChan() chan interface{}
    Tomb() *tomb.Tomb
    Apply()
    }

    type PowerableEffectFactory func(p lampbase.Powerable) Effect
    type DimLampEffectFactory func(d lampbase.DimLamp) Effect
    type ColorLampEffectFactory func(c lampbase.ColorLamp) Effect
    type StripeLampEffectFactory func(s lampbase.StripeLamp) Effect

    Also lamp operations can cause errors since there is networking involved,
    thus I'd like the tomb to help me get the error back to the main system.
    It's also important to note that the system needs to handle several lamps
    of different types at once. The idea behind Config() is to retrieve the
    current configuration
    of my effect, JSON it, send it to the Client (Android App and probably
    Ajax) and update it with new values.
    There will probably be a registry of effects so that for each lamp I can
    list all available effects, note also that e.g. a ColorLamp impelements
    DimLamp.
    On Saturday, February 16, 2013 1:16:55 AM UTC+1, Kyle Lemons wrote:

    oops, forgot the setup call:
    http://play.golang.org/p/ulmfx8Z4OY

    you'll notice that this abstracts away the basic behavior that the
    controller needs to manage: all it needs to do is have a config and control
    updates to the lamp's colors on a periodic basis.


    On Fri, Feb 15, 2013 at 4:15 PM, Kyle Lemons <kev...@google.com<javascript:>
    wrote:
    a few comments:
    1) Use defer with locking:
    x.Lock()
    defer x.Unlock()
    return x.Y

    2) There's no real point to make an accessor for a control channel. Make
    it an exported field.
    3) Tomb is overkill for this. Kill the goroutine by closing its control
    channel.
    4) I would make an interface for the configs so you don't have to
    enumerate them in the controller code... untested and not completely
    thought out:
    http://play.golang.org/p/O1oEPcdob5


    On Fri, Feb 15, 2013 at 2:42 PM, Niklas Schnelle <niklas....@gmail.com<javascript:>
    wrote:
    Hi fellow Gophers,

    I'm writing software to control my new network attached lamp (you'll
    definitely get to see a video when it's done :-)).
    At the moment I'm in the process of developing an architecture for
    effects on a lamp e.g. a fire animation.
    Each effect runs in it's own Goroutine and controls a single lamp.
    Effects lifecycle is handled by launchpad.net/tomb
    so that I can kill an effect at any time. Then there is a channel to
    send it a new configuration while it's running e.g. to
    change the colors of the fire.
    I've got the following code and because the config is changed I already
    added locking there, I'm unsure about
    the functions returning the tomb and the channel though. They are never
    changed so my gut feeling says the functions are fine.
    However gut feeling and data races often don't work. So here is the code:
    http://pastebin.com/M0ZtCKf5
    Apply() is normaly run in it's own Goroutine so ConfigChan(), Tomb() and
    Config() are called from other Goroutines

    Greetings Niklas

    --
    You received this message because you are subscribed to the Google
    Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send
    an email to golang-nuts...@googlegroups.com <javascript:>.
    For more options, visit https://groups.google.com/groups/opt_out.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Niklas Schnelle at Feb 16, 2013 at 12:42 am
    Note a config here is not which lamp to use but e.g. which colors to use in
    the animation

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Niklas Schnelle at Feb 16, 2013 at 12:32 pm
    After sleeping on this I think your idea with the controller is great
    because it allows me to make the effects much simpler. So I think
    I'll make effects not reconfigurable while running and make the Controller
    call an Apply() function that returns a duration that tells it when to call
    it again,
    so effects can control their speed and don't care about concurrency which
    is handled by the Controller which in turn can use a struct for direct
    element access.
    Thanks a lot for that input.

    Greetings Niklas

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedFeb 15, '13 at 10:42p
activeFeb 16, '13 at 12:32p
posts6
users2
websitegolang.org

2 users in discussion

Niklas Schnelle: 4 posts Kyle Lemons: 2 posts

People

Translate

site design / logo © 2022 Grokbase