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

cmd/syncthing: Add more stats to usage reports (ref #3628) #4347

Closed
wants to merge 12 commits into from

Conversation

AudriusButkevicius
Copy link
Member

Tested manually.
Not sure if we need to bump the version here.

@AudriusButkevicius
Copy link
Member Author

Apart from tests, what else needs to be done here @calmh?

@calmh
Copy link
Member

calmh commented Sep 6, 2017

I think either implement what we discussed on IRC about retaining the previous report version until the new one is accepted, or a huge push to get all the stuff we really want into the report in in one swoop... Not necessarily in this PR of course, but before we let this into the wild...

@AudriusButkevicius
Copy link
Member Author

So added incremental support, but did it without paying too much attention or thinking about it.
Tested here and there, seems to work, but give it a proper review pls.

Copy link
Member

@calmh calmh left a comment

Choose a reason for hiding this comment

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

Uh, it looks reasonable but my review time got interrupted by kids and concentration went out the window so I'll make another attempt soon


func (s *usageReportingService) CommitConfiguration(from, to config.Configuration) bool {
if from.Options.URAccepted != to.Options.URAccepted || from.Options.URUniqueID != to.Options.URUniqueID || from.Options.URURL != to.Options.URURL {
s.timer.Reset(time.Duration(to.Options.URInitialDelayS) * time.Second)
Copy link
Member

Choose a reason for hiding this comment

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

I suspect this is a data race on s.timer

Copy link
Member Author

Choose a reason for hiding this comment

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

Why? s.timer is not touched once it's initialized.

@AudriusButkevicius
Copy link
Member Author

@st-review retest

@st-review
Copy link

I'm sorry, @AudriusButkevicius. I'm afraid I don't know what you mean. I know how to don't, lgtm, merge, prevent, rebuild, squash, stop.

@AudriusButkevicius
Copy link
Member Author

@st-review rebuild

@calmh
Copy link
Member

calmh commented Sep 10, 2017 via email

@AudriusButkevicius
Copy link
Member Author

Sure but that's just reads, which means it should be fine?

@calmh
Copy link
Member

calmh commented Sep 10, 2017

It's not, but don't take my word for it

package main

import (
	"fmt"
	"testing"
	"time"
)

func TestTimer(t *testing.T) {
	test := &test{
		t: time.NewTimer(0),
	}
	go test.Serve()
	for i := 0; i < 5; i++ {
		test.Commit()
		time.Sleep(time.Second)
	}
}

type test struct {
	t *time.Timer
}

func (t *test) Serve() {
	t.t.Reset(0)
	for {
		<-t.t.C
		fmt.Println("tick")
		t.t.Reset(time.Second)
	}
}

func (t *test) Commit() {
	fmt.Println("resetting timer")
	t.t.Reset(10 * time.Millisecond)
}
jb@unu:~/t/timer $ go test -race
resetting timer
tick
tick
==================
WARNING: DATA RACE
Write at 0x00c420088650 by goroutine 6:
  time.(*Timer).Reset()
      /usr/local/go1.9/src/time/sleep.go:127 +0x98
  _/Users/jb/tmp/timer.(*test).Commit()
      /Users/jb/tmp/timer/timer_test.go:35 +0xb1
  _/Users/jb/tmp/timer.TestTimer()
      /Users/jb/tmp/timer/timer_test.go:15 +0xb8
  testing.tRunner()
      /usr/local/go1.9/src/testing/testing.go:746 +0x16c

Previous write at 0x00c420088650 by goroutine 8:
  time.(*Timer).Reset()
      /usr/local/go1.9/src/time/sleep.go:127 +0x98
  _/Users/jb/tmp/timer.(*test).Serve()
      /Users/jb/tmp/timer/timer_test.go:25 +0x59

@AudriusButkevicius
Copy link
Member Author

Is that a race internally setting something in the timer or accessing the timer in general.
As in, if I wrap things in a lock, do I need to wrap the channel retrieval with a lock too?

@calmh
Copy link
Member

calmh commented Sep 10, 2017

I think it's just the Reset() that does internal unlocked writes, so protecting that should be enough. There's a whole discussion in the Reset() documentation that says you can't do Reset() concurrently with the channel read, but I think that is for correctness and not relevant as we don't really care if the timer fires at exactly the same time we call Reset(). (That stuff matters if the timer represents a timeout error that should not fire in case of Reset() etc but we don't care.)

The race detector should tell us if it's otherwise.

@AudriusButkevicius
Copy link
Member Author

Anyway, this uses a channel now.

if ($scope.system && $scope.config.options.urSeen < $scope.system.urVersionMax) {
// Usage reporting format has changed, prompt the user to re-accept.
$('#ur').modal();
}
Copy link
Member Author

Choose a reason for hiding this comment

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

This is a bit racy, as we rely on $scope.system being populated first to actually do the prompt.

@calmh
Copy link
Member

calmh commented Sep 20, 2017

The block stats and connection types objects are shown also in the version two preview:

screen shot 2017-09-20 at 08 28 28

@AudriusButkevicius
Copy link
Member Author

Copy link
Member

@calmh calmh left a comment

Choose a reason for hiding this comment

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

Otherwise lgtm

@@ -6,7 +6,7 @@
<p translate>The aggregated statistics are publicly available at the URL below.</p>
<p><a href="https://data.syncthing.net/" target="_blank">https://data.syncthing.net/</a></p>
<label translate>Version</label>
<select class="form-control" ng-model="reportDataPreviewVersion" ng-change="refreshReportDataPreview()">
<select id="urPreviewVersion" class="form-control" ng-model="$parent.$parent.reportDataPreviewVersion" ng-change="refreshReportDataPreview()" >
Copy link
Member

Choose a reason for hiding this comment

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

... 😷

@@ -234,13 +234,14 @@ func (s *usageReportingService) sendUsageReport() error {

func (s *usageReportingService) Serve() {
s.stop = make(chan struct{})
s.timer.Reset(time.Duration(s.cfg.Options().URInitialDelayS) * time.Second)

t := time.NewTimer(time.Duration(s.cfg.Options().URInitialDelayS) * time.Second)
Copy link
Member

Choose a reason for hiding this comment

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

defer t.Stop()

@@ -133,7 +135,11 @@ angular.module('syncthing.core')
}).error($scope.emitHTTPError);

$http.get(urlbase + '/svc/report').success(function (data) {
$scope.reportData = data;
$scope.reportDataPreview = $scope.reportData = data;
if ($scope.system && $scope.config.options.urSeen < $scope.system.urVersionMax) {
Copy link
Member

Choose a reason for hiding this comment

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

This might not work for candidate releases. For those we set urAccepted = urVersionMax (or the equivalent what the variables are a called) on startup, but we don't tweak urSeen so this dialog would be triggered unnecessarily.

@AudriusButkevicius
Copy link
Member Author

Updated and added usage stats for features of the ignore patterns.

}

// Noops, remove
if strings.HasPrefix(line, "**") {
Copy link
Member

Choose a reason for hiding this comment

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

I don't think doube star prefixes are noops, e.g. **/temp isn't rooted, is it?

@AudriusButkevicius
Copy link
Member Author

I need to remove **/ I guess as that is equivalent behaviour without the prefix.

@AudriusButkevicius
Copy link
Member Author

@st-review rebuild

@calmh
Copy link
Member

calmh commented Oct 7, 2017

This is good to go I think?

@AudriusButkevicius
Copy link
Member Author

Yes

@calmh
Copy link
Member

calmh commented Oct 12, 2017

@st-review merge

@st-review
Copy link

👌 Merged as 2760d03. Thanks, @AudriusButkevicius!

@st-review st-review closed this Oct 12, 2017
st-review pushed a commit that referenced this pull request Oct 12, 2017
@AudriusButkevicius
Copy link
Member Author

I assume this need schema changes in the db?

@calmh
Copy link
Member

calmh commented Oct 12, 2017

Yes, it needs handling on the receiving side. I think we have a couple of migrations in that code already, basically ALTER TABLE ... ADD COLUMN and new fields in the struct it unmarshals to etc

@calmh
Copy link
Member

calmh commented Oct 12, 2017

I guess if you're looking at a new challenge maybe refactor it to use a json document type in the database so that we'd just need to hack the various analytics parts in the future and not the whole storage part

@st-review st-review added the pr-merged Legacy label used in the past for pull requests merged to the main tree label Jan 15, 2018
@st-review st-review added the frozen-due-to-age Issues closed and untouched for a long time, together with being locked for discussion label Oct 12, 2018
@syncthing syncthing locked and limited conversation to collaborators Oct 12, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
frozen-due-to-age Issues closed and untouched for a long time, together with being locked for discussion pr-merged Legacy label used in the past for pull requests merged to the main tree
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants