Merge pull request #848 from pluby/discovery

Simpler entry of locally discovered nodes
This commit is contained in:
Jakob Borg 2014-10-16 09:11:08 +02:00
commit b012f77475
4 changed files with 53 additions and 33 deletions

View File

@ -34,6 +34,7 @@ import (
"code.google.com/p/go.crypto/bcrypt" "code.google.com/p/go.crypto/bcrypt"
"github.com/syncthing/syncthing/internal/auto" "github.com/syncthing/syncthing/internal/auto"
"github.com/syncthing/syncthing/internal/config" "github.com/syncthing/syncthing/internal/config"
"github.com/syncthing/syncthing/internal/discover"
"github.com/syncthing/syncthing/internal/events" "github.com/syncthing/syncthing/internal/events"
"github.com/syncthing/syncthing/internal/logger" "github.com/syncthing/syncthing/internal/logger"
"github.com/syncthing/syncthing/internal/model" "github.com/syncthing/syncthing/internal/model"
@ -451,7 +452,17 @@ func restPostDiscoveryHint(w http.ResponseWriter, r *http.Request) {
} }
func restGetDiscovery(w http.ResponseWriter, r *http.Request) { func restGetDiscovery(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(discoverer.All()) w.Header().Set("Content-Type", "application/json; charset=utf-8")
registry := discoverer.All()
// Device ids can't be marshalled as keys so we need to manually
// rebuild this map using strings.
devices := make(map[string][]discover.CacheEntry, len(registry))
for device, _ := range registry {
devices[device.String()] = registry[device]
}
json.NewEncoder(w).Encode(devices)
} }
func restGetReport(m *model.Model, w http.ResponseWriter, r *http.Request) { func restGetReport(m *model.Model, w http.ResponseWriter, r *http.Request) {

View File

@ -666,15 +666,21 @@ syncthing.controller('SyncthingCtrl', function ($scope, $http, $translate, $loca
}; };
$scope.addDevice = function () { $scope.addDevice = function () {
$scope.currentDevice = { $http.get(urlbase + '/discovery')
AddressesStr: 'dynamic', .success(function (registry) {
Compression: true, $scope.discovery = registry;
Introducer: false })
}; .then(function () {
$scope.editingExisting = false; $scope.currentDevice = {
$scope.editingSelf = false; AddressesStr: 'dynamic',
$scope.deviceEditor.$setPristine(); Compression: true,
$('#editDevice').modal(); Introducer: false
};
$scope.editingExisting = false;
$scope.editingSelf = false;
$scope.deviceEditor.$setPristine();
$('#editDevice').modal();
});
}; };
$scope.deleteDevice = function () { $scope.deleteDevice = function () {

View File

@ -383,7 +383,10 @@
<form role="form" name="deviceEditor"> <form role="form" name="deviceEditor">
<div class="form-group" ng-class="{'has-error': deviceEditor.deviceID.$invalid && deviceEditor.deviceID.$dirty}"> <div class="form-group" ng-class="{'has-error': deviceEditor.deviceID.$invalid && deviceEditor.deviceID.$dirty}">
<label translate for="deviceID">Device ID</label> <label translate for="deviceID">Device ID</label>
<input ng-if="!editingExisting" name="deviceID" id="deviceID" class="form-control text-monospace" type="text" ng-model="currentDevice.DeviceID" required valid-deviceid></input> <input ng-if="!editingExisting" name="deviceID" id="deviceID" class="form-control text-monospace" type="text" ng-model="currentDevice.DeviceID" required valid-deviceid list="discovery-list" />
<datalist id="discovery-list" ng-if="!editingExisting">
<option ng-repeat="(id,address) in discovery" value="{{ id }}" />
</datalist>
<div ng-if="editingExisting" class="well well-sm text-monospace">{{currentDevice.DeviceID}}</div> <div ng-if="editingExisting" class="well well-sm text-monospace">{{currentDevice.DeviceID}}</div>
<p class="help-block"> <p class="help-block">
<span translate ng-if="deviceEditor.deviceID.$valid || deviceEditor.deviceID.$pristine">The device ID to enter here can be found in the "Edit > Show ID" dialog on the other device. Spaces and dashes are optional (ignored).</span> <span translate ng-if="deviceEditor.deviceID.$valid || deviceEditor.deviceID.$pristine">The device ID to enter here can be found in the "Edit > Show ID" dialog on the other device. Spaces and dashes are optional (ignored).</span>

View File

@ -39,7 +39,7 @@ type Discoverer struct {
cacheLifetime time.Duration cacheLifetime time.Duration
broadcastBeacon beacon.Interface broadcastBeacon beacon.Interface
multicastBeacon beacon.Interface multicastBeacon beacon.Interface
registry map[protocol.DeviceID][]cacheEntry registry map[protocol.DeviceID][]CacheEntry
registryLock sync.RWMutex registryLock sync.RWMutex
extServer string extServer string
extPort uint16 extPort uint16
@ -51,9 +51,9 @@ type Discoverer struct {
extAnnounceOKmut sync.Mutex extAnnounceOKmut sync.Mutex
} }
type cacheEntry struct { type CacheEntry struct {
addr string Address string
seen time.Time Seen time.Time
} }
var ( var (
@ -68,7 +68,7 @@ func NewDiscoverer(id protocol.DeviceID, addresses []string) *Discoverer {
globalBcastIntv: 1800 * time.Second, globalBcastIntv: 1800 * time.Second,
errorRetryIntv: 60 * time.Second, errorRetryIntv: 60 * time.Second,
cacheLifetime: 5 * time.Minute, cacheLifetime: 5 * time.Minute,
registry: make(map[protocol.DeviceID][]cacheEntry), registry: make(map[protocol.DeviceID][]CacheEntry),
} }
} }
@ -139,16 +139,16 @@ func (d *Discoverer) Lookup(device protocol.DeviceID) []string {
if len(cached) > 0 { if len(cached) > 0 {
addrs := make([]string, len(cached)) addrs := make([]string, len(cached))
for i := range cached { for i := range cached {
addrs[i] = cached[i].addr addrs[i] = cached[i].Address
} }
return addrs return addrs
} else if len(d.extServer) != 0 { } else if len(d.extServer) != 0 {
addrs := d.externalLookup(device) addrs := d.externalLookup(device)
cached = make([]cacheEntry, len(addrs)) cached = make([]CacheEntry, len(addrs))
for i := range addrs { for i := range addrs {
cached[i] = cacheEntry{ cached[i] = CacheEntry{
addr: addrs[i], Address: addrs[i],
seen: time.Now(), Seen: time.Now(),
} }
} }
@ -169,11 +169,11 @@ func (d *Discoverer) Hint(device string, addrs []string) {
}) })
} }
func (d *Discoverer) All() map[protocol.DeviceID][]cacheEntry { func (d *Discoverer) All() map[protocol.DeviceID][]CacheEntry {
d.registryLock.RLock() d.registryLock.RLock()
devices := make(map[protocol.DeviceID][]cacheEntry, len(d.registry)) devices := make(map[protocol.DeviceID][]CacheEntry, len(d.registry))
for device, addrs := range d.registry { for device, addrs := range d.registry {
addrsCopy := make([]cacheEntry, len(addrs)) addrsCopy := make([]CacheEntry, len(addrs))
copy(addrsCopy, addrs) copy(addrsCopy, addrs)
devices[device] = addrsCopy devices[device] = addrsCopy
} }
@ -365,14 +365,14 @@ func (d *Discoverer) registerDevice(addr net.Addr, device Device) bool {
deviceAddr = ua.String() deviceAddr = ua.String()
} }
for i := range current { for i := range current {
if current[i].addr == deviceAddr { if current[i].Address == deviceAddr {
current[i].seen = time.Now() current[i].Seen = time.Now()
goto done goto done
} }
} }
current = append(current, cacheEntry{ current = append(current, CacheEntry{
addr: deviceAddr, Address: deviceAddr,
seen: time.Now(), Seen: time.Now(),
}) })
done: done:
} }
@ -388,7 +388,7 @@ func (d *Discoverer) registerDevice(addr net.Addr, device Device) bool {
if len(current) > len(orig) { if len(current) > len(orig) {
addrs := make([]string, len(current)) addrs := make([]string, len(current))
for i := range current { for i := range current {
addrs[i] = current[i].addr addrs[i] = current[i].Address
} }
events.Default.Log(events.DeviceDiscovered, map[string]interface{}{ events.Default.Log(events.DeviceDiscovered, map[string]interface{}{
"device": id.String(), "device": id.String(),
@ -468,11 +468,11 @@ func (d *Discoverer) externalLookup(device protocol.DeviceID) []string {
return addrs return addrs
} }
func (d *Discoverer) filterCached(c []cacheEntry) []cacheEntry { func (d *Discoverer) filterCached(c []CacheEntry) []CacheEntry {
for i := 0; i < len(c); { for i := 0; i < len(c); {
if ago := time.Since(c[i].seen); ago > d.cacheLifetime { if ago := time.Since(c[i].Seen); ago > d.cacheLifetime {
if debug { if debug {
l.Debugf("removing cached address %s: seen %v ago", c[i].addr, ago) l.Debugf("removing cached address %s: seen %v ago", c[i].Address, ago)
} }
c[i] = c[len(c)-1] c[i] = c[len(c)-1]
c = c[:len(c)-1] c = c[:len(c)-1]