Provide guidance on how to 'async' additems to a list? #77

Closed
opened 2021-08-08 15:41:21 +00:00 by caninodev · 1 comment

Disclaimer: I am just learning about concurrency (actually because of the following use case?). I have a slice of IDs for postings. Rather than batch fetch all the related data with each ID (which would cause a potentially long wait before the screen is drawn), I thought that this would be an ideal use for Go's chan type. (Please correct me if I am wrong).

So I thought to have the following:

func (f *Firebase) Subscribe(request RequestType) chan Item {
	var err error
	var IDs []uint
	IDs, err = f.fetch(request)
	if err != nil {
		log.Fatalf("error retrieving IDs: %v", err)
	}

	var item Item
	items := make(chan Item, 5)
        go func() {
		for ID := range IDs {
			item, err = f.post(uint(ID))

			if err != nil {
				log.Fatalf("error:  %v", err)
			}
			log.Print(item.Title())
			items <- item
		}
    }()
	return items
}

Then when coding out the ui, I have the following:

func (u *ui) ListView() {
	lv := cview.NewList()
	reset := func() {
		lv.Clear()
        for item := <- u.firebase.Subscribe(hackernews.NewStories) {
			tm := time.Unix(int64(item.Time()), 0).UTC().Format(time.RFC1123)
			listItem := cview.NewListItem(item.Title())
			listItem.SetSecondaryText(fmt.Sprintf("(%s) by: %s, on %s", item.URL(), item.By(), tm))
			lv.AddItem(listItem)
		}
	quitItem := cview.NewListItem("Quit")
	quitItem.SetSecondaryText("Press to exit")
	quitItem.SetShortcut('q')
	quitItem.SetSelectedFunc(func() {
			u.Stop()
	})
	lv.AddItem(quitItem)
	lv.ContextMenuList().SetItemEnabled(1, false)
    
	lv.AddContextItem("Delete item", 'd', func(index int) {
		lv.RemoveItem(index)

		if lv.GetItemCount() == 0 {
			lv.ContextMenuList().SetItemEnabled(0, false)
			lv.ContextMenuList().SetItemEnabled(1, false)
		}
		lv.ContextMenuList().SetItemEnabled(3, true)
	})
	lv.AddContextItem("Reset", 'r', func(index int) {
    	reset()
    })
	u.SetRoot(lv, true)
	reset()
}

And yet the output is not rendered. What have I done wrong? (The full source can be found at github.com/CaninoDev/hackernewsterm (the refresh branch) I would appreciate any help in clarifying whether this is a use case for chan.

Disclaimer: I am just learning about concurrency (actually because of the following use case?). I have a slice of IDs for postings. Rather than batch fetch all the related data with each ID (which would cause a potentially long wait before the screen is drawn), I thought that this would be an ideal use for Go's `chan` type. (Please correct me if I am wrong). So I thought to have the following: ```go func (f *Firebase) Subscribe(request RequestType) chan Item { var err error var IDs []uint IDs, err = f.fetch(request) if err != nil { log.Fatalf("error retrieving IDs: %v", err) } var item Item items := make(chan Item, 5) go func() { for ID := range IDs { item, err = f.post(uint(ID)) if err != nil { log.Fatalf("error: %v", err) } log.Print(item.Title()) items <- item } }() return items } ``` Then when coding out the ui, I have the following: ```go func (u *ui) ListView() { lv := cview.NewList() reset := func() { lv.Clear() for item := <- u.firebase.Subscribe(hackernews.NewStories) { tm := time.Unix(int64(item.Time()), 0).UTC().Format(time.RFC1123) listItem := cview.NewListItem(item.Title()) listItem.SetSecondaryText(fmt.Sprintf("(%s) by: %s, on %s", item.URL(), item.By(), tm)) lv.AddItem(listItem) } quitItem := cview.NewListItem("Quit") quitItem.SetSecondaryText("Press to exit") quitItem.SetShortcut('q') quitItem.SetSelectedFunc(func() { u.Stop() }) lv.AddItem(quitItem) lv.ContextMenuList().SetItemEnabled(1, false) lv.AddContextItem("Delete item", 'd', func(index int) { lv.RemoveItem(index) if lv.GetItemCount() == 0 { lv.ContextMenuList().SetItemEnabled(0, false) lv.ContextMenuList().SetItemEnabled(1, false) } lv.ContextMenuList().SetItemEnabled(3, true) }) lv.AddContextItem("Reset", 'r', func(index int) { reset() }) u.SetRoot(lv, true) reset() } ``` And yet the output is not rendered. What have I done wrong? (The full source can be found at github.com/CaninoDev/hackernewsterm (the refresh branch) I would appreciate any help in clarifying whether this is a use case for chan.

The application is drawn after input events automatically, but must otherwise be drawn by calling Draw or QueueUpdateDraw. I've just added a Draw call to SetRoot to make changes immediately visible.

The application is drawn after input events automatically, but must otherwise be drawn by calling `Draw` or `QueueUpdateDraw`. I've just added a `Draw` call to `SetRoot` to make changes immediately visible.
Sign in to join this conversation.
No Milestone
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: tslocum/cview#77
There is no content yet.