Exemple #1
0
func (this *DataMgr) downloadLoop() {
	this.Log.Printf("Entering download loop")
	this.lock.Lock() // Lock is held *except* when doing remote calls & sleeping
	// While I'm not closing
	for !this.isClosing {
		this.SyncMgr.Log.Printf("Looking things to download\n")
		// Get a object to download
		var key string
		row := this.Db.SingleQuery("SELECT key FROM Blob WHERE needs_download = 1")
		if !this.Db.MaybeScan(row, &key) {
			this.Log.Printf("Nothing to download, sleeping\n")
			this.download.Wait()
			continue
		}
		friends := this.allAdverts(key)
		if len(friends) == 0 {
			this.Log.Printf("Strangely got a download where len(friends) = 0")
			this.Db.Exec("UPDATE Blob SET needs_download = 0 WHERE key = ?", key)
			continue
		}
		friend := friends[rand.Intn(len(friends))]
		obj := this.getObj(key)
		obj.startDownload()
		this.writeObj(obj)
		this.lock.Unlock()
		this.Log.Printf("Doing a download of %s from %d!\n", key, friend)

		var send_buf bytes.Buffer
		transfer.Encode(&send_buf, key)
		tmppath := path.Join(this.incoming, crypto.RandomString())
		file, _ := os.Create(tmppath)
		hasher := crypto.NewHasher()
		both := io.MultiWriter(file, hasher)

		tryTime := time.Now()
		err := this.Send(link.ServiceData, friend, &send_buf, both)
		if err != nil && time.Now().Sub(tryTime) < 5*time.Second {
			// TODO: Make this not suck
			time.Sleep(5 * time.Second)
		}
		if err != nil {
			this.Log.Printf("Download failed: %s", err)
		} else {
			this.Log.Printf("Download worked!")
		}
		this.lock.Lock()
		obj = this.getObj(key)
		obj.finishDownload(tmppath, err == nil)
		this.writeObj(obj)
	}
	this.lock.Unlock()
	this.goRoutines.Done()
}
Exemple #2
0
// Reads from io.Reader and generates a new object, put it to the meta-data layer
func (this *DataMgr) PutData(topic string, key string, writer *crypto.SecretIdentity, stream io.Reader) error {
	this.Log.Printf("Putting data: %s, %s", topic, key)
	// Write the object to disk
	tmppath := path.Join(this.incoming, crypto.RandomString())
	file, err := os.Create(tmppath)
	if err != nil {
		return err
	}
	hasher := crypto.NewHasher()
	both := io.MultiWriter(file, hasher)
	_, err = io.Copy(both, stream)
	if err != nil {
		_ = os.Remove(tmppath) // Ignore errors
		return err
	}
	digest := hasher.Finalize()
	okey := digest.String()

	// Add info to DB
	this.lock.Lock()
	obj := this.getObj(okey)
	obj.newFile(tmppath)
	obj.Holds++
	this.writeObj(obj)
	this.lock.Unlock()

	// Put to meta-data layer
	data, _ := transfer.EncodeBytes(digest)
	err = this.MetaMgr.Put(topic, writer, key, data)

	// Remove hold
	this.lock.Lock()
	obj = this.getObj(okey)
	obj.Holds--
	this.writeObj(obj)
	this.lock.Unlock()

	return err
}