Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Notifications system #321

Closed
wants to merge 14 commits into from
Closed

[WIP] Notifications system #321

wants to merge 14 commits into from

Conversation

andreynering
Copy link
Contributor

WIP: still in an early stage

@andreynering andreynering added type/feature Completely new functionality. Can only be merged if feature freeze is not active. pr/wip This PR is not ready for review labels Nov 30, 2016
new(UpdateTask), new(HookTask),
new(Team), new(OrgUser), new(TeamUser), new(TeamRepo),
new(Notice), new(EmailAddress))
new(User),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! This has been messing with my OCD for a while 😆

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about reorder them?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lunny in alphabetical order?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If order doesn't need to match the order in which fields are defined in the structure, then it makes sense to me to sort them alphabetically.

Copy link
Member

@bkcsoft bkcsoft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few things

)

const (
NotificationStatusUnread = "U"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use iota ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer string because it is more readable (while querying the database).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So you're throwing away performance for readibility of the DB? 🙂

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One char string: 1 byte
Int: 4 bytes, unless we used smallint, it would be 2 bytes in the DB.

I don't think there will be a performance difference at all. But I'm open to change to int if most of you prefer. 😉

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would also prefer iota.

RepoID int64 `xorm:"INDEX NOT NULL"`

Status string `xorm:"VARCHAR(1) INDEX NOT NULL"`
Source string `xorm:"VARCHAR(1) INDEX NOT NULL"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should be type NotificationStatus string and type NotificationSource string (if string, see above comment)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^

Status NotificationStatus
Source NotificationSource

now = time.Now()
nowUnix = now.Unix()
)
n.Updated = now
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gofmt

if err := sess.Begin(); err != nil {
return err
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no new-line IMO

for _, watch := range watches {
exists, err := issueNotificationExists(sess, watch.UserID, watch.RepoID)
if err != nil {
return err
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not put the errors in a channel and check that one afterwards... what happens now is that if a User is improperly deleted, no-one will get any notifications 😕

Copy link
Contributor Author

@andreynering andreynering Dec 1, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, you're right. Ideally we should have foreign keys, so that wouldn't happen. 😄

But I think I'll call this in a goroutine, and just log on any error, instead of break.

}

if err != nil {
return err
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above

@andreynering andreynering mentioned this pull request Dec 1, 2016
10 tasks
@strk
Copy link
Member

strk commented Dec 2, 2016

Does this address gogs/gogs#2929 ?

@tboerger tboerger added the lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. label Dec 2, 2016
@andreynering
Copy link
Contributor Author

@strk It will.

@strk
Copy link
Member

strk commented Dec 2, 2016 via email

@tboerger tboerger added this to the 1.1.0 milestone Dec 2, 2016
@bkcsoft
Copy link
Member

bkcsoft commented Dec 6, 2016

Just a thought... Can't this be "extracted" into a Service? Since (as far as I can read) this will block issue-creation response until all watchers have been notified

Setting it up as a Service also have the added bonus of being able to move Mail-sending and such to the background (not sure how this works currently though)

@andreynering
Copy link
Contributor Author

@bkcsoft Yes, that's a good idea

@bkcsoft
Copy link
Member

bkcsoft commented Dec 6, 2016

@andreynering Preferably use channels 😉

struct NotificationService type {
  queue chan *models.Notification
}

func (ns *NotificationService) Notify(in *models.Notification) {
  ns.queue <- in
}

func(ns *NotificationService) Run() {
  for {
    select {
    case notif<- ns.queue: // Will stall until queue to process
      ns.processNotification(notif)
    }
  }
}

@@ -453,6 +454,8 @@ func NewIssuePost(ctx *context.Context, form auth.CreateIssueForm) {
return
}

notification.Service.NotifyIssue(issue)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be put in background too ?
is: go notification.Service.NotifyIssue(issues)

If I read the code correctly the NotifyIssue writes into a channel, is that operation immediate or blocks until someone reads from the channel ? (lame gopher here)

Copy link
Contributor Author

@andreynering andreynering Dec 11, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have a good point. Channels act like a queue, so I think it will block until it's consumed by the service.

We can use buffered channels [1], but I think we will have a panic if we exceed the buffer size. I will make some tests.

[1] https://gobyexample.com/channel-buffering

Edit: buffered channels will do the trick: https://tour.golang.org/concurrency/3

- Replace old IssueUser table with Notifications
- Mark notification as read on opening
- Changing creation of notifications from router to models
@bkcsoft
Copy link
Member

bkcsoft commented Dec 20, 2016

refactor

This is growing quite huge, and yes I'm aware that it's a large feature, but could you possibly do this in two steps? first one being the bare NotificationService, then in the second one actually start using it, because it's going to be a pain to review all this in one go 😕

@andreynering
Copy link
Contributor Author

@bkcsoft Hmm... I tried to keep the commit history, but yeah, I agree that it's big.

I'll split then, but I'll have to wait the 1.0.0 release, I think.

@andreynering andreynering deleted the notifications branch December 20, 2016 22:16
@andreynering andreynering mentioned this pull request Dec 20, 2016
2 tasks
@andreynering
Copy link
Contributor Author

Splitted. Step 1 at #429

@tboerger tboerger added reviewed/invalid and removed type/feature Completely new functionality. Can only be merged if feature freeze is not active. lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. pr/wip This PR is not ready for review labels Dec 21, 2016
@tboerger tboerger removed this from the 1.1.0 milestone Dec 21, 2016
@go-gitea go-gitea locked and limited conversation to collaborators Nov 23, 2020
@delvh delvh added issue/not-a-bug The reported issue is the intended behavior or the problem is not inside Gitea and removed reviewed/invalid labels Oct 7, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
issue/not-a-bug The reported issue is the intended behavior or the problem is not inside Gitea
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants