I have simple task that already done in javascript using pubsub, here is the task:
I have object let say A
and another 2 object that have interest in some element(string in this case), let say Foo
interest in element m, n
and Bar
interest in element n, o, p
. The interest can intersect.
The A object have method adding/remove element and when that object contain m, n
element which Foo
interest in, then that object stored in Foo
here's the pseudo code in javascript using pubsub
var A = {};
var Foo = {
interests: ['m', 'n'],
storedObj: {},
tempObj: {}
};
// Bar same as Foo with different interest ['n', 'o', 'p']
// somewhere in Foo and Bar constructor
// Foo and Bar subscribe too each interests element
// for each interests when add
subscribe('add'+interest, function(obj) {
// store this obj in tempObj and increment until satisfy all
// interest
tempObj[obj]++;
// if this obj satisfy all interest then store it in array of obj
if(tempObj[obj] === len(interests)) {
storedObj[obj] = true;
}
});
// for each interests when remove
subscribe('remove'+interest, function(obj) {
// remove from storedObj
delete storedObj[obj];
// decrement tempObj so it can be used for later if the interest
// is adding again
tempObj[obj]--;
});
// inside A prototype
prototype.add = function(interest) {
publish('add'+interest, this);
return this;
}
prototype.remove = function(interest) {
publish('remove'+interest, this);
return this;
}
// implementation
A.add('m')
.add('n')
.add('o')
// then A is stored inside Foo but not in Bar because A doesn't have
// `p`, but it still stored Bar.tempObj and have value 2 and waiting
// for `p` to be add
A.remove('m')
.add('p')
// then A is removed from Foo and stored in Bar
I want to porting this task into golang but i don't want using pubsub, i want more idiomatic to golang way. NOTE: i already done using pubsub in golang as well.
Can you show me how to do it in golang? i'm thingking using channel, but and can't find the solution.
Just to give you an idea, not necessarily your real use case.
package main
import (
"fmt"
"time"
)
type Publisher struct {
subscription map[string]chan string
}
func (p *Publisher)Subscribe(interest string) chan string{
if p.subscription == nil {
p.subscription = make(map[string]chan string)
}
p.subscription[interest] = make(chan string)
return p.subscription[interest]
}
func (p *Publisher) Add(val string) {
if p.subscription[val] != nil {
fmt.Println("Adding " + val)
p.subscription[val] <- "added " + val
}
}
func (p *Publisher) Remove(val string) {
if p.subscription[val] != nil {
p.subscription[val] <- "removed " + val
}
}
type Subscriber struct {
subscriptions [] chan string
publisher *Publisher
}
func (s *Subscriber) RegisterInterest(interest string){
s.subscriptions = append(s.subscriptions, s.publisher.Subscribe(interest))
}
func (s *Subscriber) run(channel chan string) {
for {
fmt.Println("Waiting for message")
m := <- channel
fmt.Println("Got message : " + m)
}
}
func (s *Subscriber) Listen() {
for _, elem := range s.subscriptions {
go s.run(elem)
}
}
func main() {
pub := Publisher{}
sub := &Subscriber{publisher: &pub}
sub.RegisterInterest("m")
sub.RegisterInterest("n")
sub.Listen()
pub.Add("m")
pub.Add("n")
pub.Remove("m")
pub.Remove("n")
time.Sleep(time.Second * 10)
}