mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-18 09:53:48 +00:00
Merge pull request #334 from ethersphere/improved_tracing
improved tracing
This commit is contained in:
commit
166c3e7e5b
7 changed files with 80 additions and 32 deletions
|
|
@ -480,16 +480,16 @@ func (tab *Table) doRevalidate(done chan<- struct{}) {
|
||||||
b := tab.buckets[bi]
|
b := tab.buckets[bi]
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// The node responded, move it to the front.
|
// The node responded, move it to the front.
|
||||||
log.Debug("Revalidated node", "b", bi, "id", last.ID)
|
log.Trace("Revalidated node", "b", bi, "id", last.ID)
|
||||||
b.bump(last)
|
b.bump(last)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// No reply received, pick a replacement or delete the node if there aren't
|
// No reply received, pick a replacement or delete the node if there aren't
|
||||||
// any replacements.
|
// any replacements.
|
||||||
if r := tab.replace(b, last); r != nil {
|
if r := tab.replace(b, last); r != nil {
|
||||||
log.Debug("Replaced dead node", "b", bi, "id", last.ID, "ip", last.IP, "r", r.ID, "rip", r.IP)
|
log.Trace("Replaced dead node", "b", bi, "id", last.ID, "ip", last.IP, "r", r.ID, "rip", r.IP)
|
||||||
} else {
|
} else {
|
||||||
log.Debug("Removed dead node", "b", bi, "id", last.ID, "ip", last.IP)
|
log.Trace("Removed dead node", "b", bi, "id", last.ID, "ip", last.IP)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -594,13 +594,13 @@ running:
|
||||||
// This channel is used by AddPeer to add to the
|
// This channel is used by AddPeer to add to the
|
||||||
// ephemeral static peer list. Add it to the dialer,
|
// ephemeral static peer list. Add it to the dialer,
|
||||||
// it will keep the node connected.
|
// it will keep the node connected.
|
||||||
srv.log.Debug("Adding static node", "node", n)
|
srv.log.Trace("Adding static node", "node", n)
|
||||||
dialstate.addStatic(n)
|
dialstate.addStatic(n)
|
||||||
case n := <-srv.removestatic:
|
case n := <-srv.removestatic:
|
||||||
// This channel is used by RemovePeer to send a
|
// This channel is used by RemovePeer to send a
|
||||||
// disconnect request to a peer and begin the
|
// disconnect request to a peer and begin the
|
||||||
// stop keeping the node connected
|
// stop keeping the node connected
|
||||||
srv.log.Debug("Removing static node", "node", n)
|
srv.log.Trace("Removing static node", "node", n)
|
||||||
dialstate.removeStatic(n)
|
dialstate.removeStatic(n)
|
||||||
if p, ok := peers[n.ID]; ok {
|
if p, ok := peers[n.ID]; ok {
|
||||||
p.Disconnect(DiscRequested)
|
p.Disconnect(DiscRequested)
|
||||||
|
|
|
||||||
|
|
@ -242,6 +242,7 @@ func (self *Api) Retrieve(key storage.Key) storage.LazySectionReader {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Api) Store(data io.Reader, size int64) (key storage.Key, wait func(), err error) {
|
func (self *Api) Store(data io.Reader, size int64) (key storage.Key, wait func(), err error) {
|
||||||
|
log.Debug("api.store", "size", size)
|
||||||
return self.dpa.Store(data, size)
|
return self.dpa.Store(data, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -250,7 +251,7 @@ type ErrResolve error
|
||||||
// DNS Resolver
|
// DNS Resolver
|
||||||
func (self *Api) Resolve(uri *URI) (storage.Key, error) {
|
func (self *Api) Resolve(uri *URI) (storage.Key, error) {
|
||||||
apiResolveCount.Inc(1)
|
apiResolveCount.Inc(1)
|
||||||
log.Trace(fmt.Sprintf("Resolving : %v", uri.Addr))
|
log.Trace("resolving", "uri", uri.Addr)
|
||||||
|
|
||||||
// if the URI is immutable, check if the address is a hash
|
// if the URI is immutable, check if the address is a hash
|
||||||
isHash := hashMatcher.MatchString(uri.Addr)
|
isHash := hashMatcher.MatchString(uri.Addr)
|
||||||
|
|
@ -307,6 +308,7 @@ func (self *Api) Put(content, contentType string) (k storage.Key, wait func(), e
|
||||||
// to resolve basePath to content using dpa retrieve
|
// to resolve basePath to content using dpa retrieve
|
||||||
// it returns a section reader, mimeType, status and an error
|
// it returns a section reader, mimeType, status and an error
|
||||||
func (self *Api) Get(key storage.Key, path string) (reader storage.LazySectionReader, mimeType string, status int, err error) {
|
func (self *Api) Get(key storage.Key, path string) (reader storage.LazySectionReader, mimeType string, status int, err error) {
|
||||||
|
log.Debug("api.get", "key", key, "path", path)
|
||||||
apiGetCount.Inc(1)
|
apiGetCount.Inc(1)
|
||||||
trie, err := loadManifest(self.dpa, key, nil)
|
trie, err := loadManifest(self.dpa, key, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -316,9 +318,9 @@ func (self *Api) Get(key storage.Key, path string) (reader storage.LazySectionRe
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Trace(fmt.Sprintf("getEntry(%s)", path))
|
log.Trace("trie getting entry", "key", key, "path", path)
|
||||||
|
|
||||||
entry, _ := trie.getEntry(path)
|
entry, _ := trie.getEntry(path)
|
||||||
|
log.Trace("trie got entry", "key", key, "path", path)
|
||||||
|
|
||||||
if entry != nil {
|
if entry != nil {
|
||||||
// we want to be able to serve Mutable Resource Updates transparently using the bzz:// scheme
|
// we want to be able to serve Mutable Resource Updates transparently using the bzz:// scheme
|
||||||
|
|
@ -330,7 +332,7 @@ func (self *Api) Get(key storage.Key, path string) (reader storage.LazySectionRe
|
||||||
// we return a typed error instead. Since for all other purposes this is an invalid manifest,
|
// we return a typed error instead. Since for all other purposes this is an invalid manifest,
|
||||||
// any normal interfacing code will just see an error fail accordingly.
|
// any normal interfacing code will just see an error fail accordingly.
|
||||||
if entry.ContentType == ResourceContentType {
|
if entry.ContentType == ResourceContentType {
|
||||||
log.Warn("resource type", "hash", entry.Hash)
|
log.Warn("resource type", "key", key, "hash", entry.Hash)
|
||||||
return nil, entry.ContentType, http.StatusOK, &ErrResourceReturn{entry.Hash}
|
return nil, entry.ContentType, http.StatusOK, &ErrResourceReturn{entry.Hash}
|
||||||
}
|
}
|
||||||
key = common.Hex2Bytes(entry.Hash)
|
key = common.Hex2Bytes(entry.Hash)
|
||||||
|
|
@ -340,14 +342,14 @@ func (self *Api) Get(key storage.Key, path string) (reader storage.LazySectionRe
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
mimeType = entry.ContentType
|
mimeType = entry.ContentType
|
||||||
log.Trace(fmt.Sprintf("content lookup key: '%v' (%v)", key, mimeType))
|
log.Trace("content lookup key", "key", key, "mimetype", mimeType)
|
||||||
reader = self.dpa.Retrieve(key)
|
reader = self.dpa.Retrieve(key)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
status = http.StatusNotFound
|
status = http.StatusNotFound
|
||||||
apiGetNotFound.Inc(1)
|
apiGetNotFound.Inc(1)
|
||||||
err = fmt.Errorf("manifest entry for '%s' not found", path)
|
err = fmt.Errorf("manifest entry for '%s' not found", path)
|
||||||
log.Warn(fmt.Sprintf("%v", err))
|
log.Trace("manifest entry not found", "key", key, "path", path)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -121,6 +121,8 @@ type Request struct {
|
||||||
// HandlePostRaw handles a POST request to a raw bzz-raw:/ URI, stores the request
|
// HandlePostRaw handles a POST request to a raw bzz-raw:/ URI, stores the request
|
||||||
// body in swarm and returns the resulting storage key as a text/plain response
|
// body in swarm and returns the resulting storage key as a text/plain response
|
||||||
func (s *Server) HandlePostRaw(w http.ResponseWriter, r *Request) {
|
func (s *Server) HandlePostRaw(w http.ResponseWriter, r *Request) {
|
||||||
|
log.Debug("handle.post.raw", "ruid", r.ruid)
|
||||||
|
|
||||||
postRawCount.Inc(1)
|
postRawCount.Inc(1)
|
||||||
if r.uri.Path != "" {
|
if r.uri.Path != "" {
|
||||||
postRawFail.Inc(1)
|
postRawFail.Inc(1)
|
||||||
|
|
@ -140,7 +142,8 @@ func (s *Server) HandlePostRaw(w http.ResponseWriter, r *Request) {
|
||||||
Respond(w, r, err.Error(), http.StatusInternalServerError)
|
Respond(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Debug(fmt.Sprintf("content for %s stored", key.Log()), "ruid", r.ruid)
|
|
||||||
|
log.Debug("stored content", "ruid", r.ruid, "key", key)
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "text/plain")
|
w.Header().Set("Content-Type", "text/plain")
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
|
|
@ -153,6 +156,8 @@ func (s *Server) HandlePostRaw(w http.ResponseWriter, r *Request) {
|
||||||
// existing manifest or to a new manifest under <path> and returns the
|
// existing manifest or to a new manifest under <path> and returns the
|
||||||
// resulting manifest hash as a text/plain response
|
// resulting manifest hash as a text/plain response
|
||||||
func (s *Server) HandlePostFiles(w http.ResponseWriter, r *Request) {
|
func (s *Server) HandlePostFiles(w http.ResponseWriter, r *Request) {
|
||||||
|
log.Debug("handle.post.files", "ruid", r.ruid)
|
||||||
|
|
||||||
postFilesCount.Inc(1)
|
postFilesCount.Inc(1)
|
||||||
contentType, params, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
|
contentType, params, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -169,6 +174,7 @@ func (s *Server) HandlePostFiles(w http.ResponseWriter, r *Request) {
|
||||||
Respond(w, r, fmt.Sprintf("cannot resolve %s: %s", r.uri.Addr, err), http.StatusInternalServerError)
|
Respond(w, r, fmt.Sprintf("cannot resolve %s: %s", r.uri.Addr, err), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
log.Debug("resolved key", "ruid", r.ruid, "key", key)
|
||||||
} else {
|
} else {
|
||||||
key, err = s.api.NewManifest()
|
key, err = s.api.NewManifest()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -176,6 +182,7 @@ func (s *Server) HandlePostFiles(w http.ResponseWriter, r *Request) {
|
||||||
Respond(w, r, err.Error(), http.StatusInternalServerError)
|
Respond(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
log.Debug("new manifest", "ruid", r.ruid, "key", key)
|
||||||
}
|
}
|
||||||
|
|
||||||
newKey, err := s.updateManifest(key, func(mw *api.ManifestWriter) error {
|
newKey, err := s.updateManifest(key, func(mw *api.ManifestWriter) error {
|
||||||
|
|
@ -197,12 +204,15 @@ func (s *Server) HandlePostFiles(w http.ResponseWriter, r *Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Debug("stored content", "ruid", r.ruid, "key", newKey)
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "text/plain")
|
w.Header().Set("Content-Type", "text/plain")
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
fmt.Fprint(w, newKey)
|
fmt.Fprint(w, newKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) handleTarUpload(req *Request, mw *api.ManifestWriter) error {
|
func (s *Server) handleTarUpload(req *Request, mw *api.ManifestWriter) error {
|
||||||
|
log.Debug("handle.tar.upload", "ruid", req.ruid)
|
||||||
tr := tar.NewReader(req.Body)
|
tr := tar.NewReader(req.Body)
|
||||||
for {
|
for {
|
||||||
hdr, err := tr.Next()
|
hdr, err := tr.Next()
|
||||||
|
|
@ -226,16 +236,17 @@ func (s *Server) handleTarUpload(req *Request, mw *api.ManifestWriter) error {
|
||||||
Size: hdr.Size,
|
Size: hdr.Size,
|
||||||
ModTime: hdr.ModTime,
|
ModTime: hdr.ModTime,
|
||||||
}
|
}
|
||||||
log.Debug(fmt.Sprintf("adding %s (%d bytes) to new manifest", entry.Path, entry.Size))
|
log.Debug("adding path to new manifest", "ruid", req.ruid, "bytes", entry.Size, "path", entry.Path)
|
||||||
contentKey, err := mw.AddEntry(tr, entry)
|
contentKey, err := mw.AddEntry(tr, entry)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error adding manifest entry from tar stream: %s", err)
|
return fmt.Errorf("error adding manifest entry from tar stream: %s", err)
|
||||||
}
|
}
|
||||||
log.Debug(fmt.Sprintf("content for %s stored", contentKey.Log()))
|
log.Debug("stored content", "ruid", req.ruid, "key", contentKey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) handleMultipartUpload(req *Request, boundary string, mw *api.ManifestWriter) error {
|
func (s *Server) handleMultipartUpload(req *Request, boundary string, mw *api.ManifestWriter) error {
|
||||||
|
log.Debug("handle.multipart.upload", "ruid", req.ruid)
|
||||||
mr := multipart.NewReader(req.Body, boundary)
|
mr := multipart.NewReader(req.Body, boundary)
|
||||||
for {
|
for {
|
||||||
part, err := mr.NextPart()
|
part, err := mr.NextPart()
|
||||||
|
|
@ -283,16 +294,17 @@ func (s *Server) handleMultipartUpload(req *Request, boundary string, mw *api.Ma
|
||||||
Size: size,
|
Size: size,
|
||||||
ModTime: time.Now(),
|
ModTime: time.Now(),
|
||||||
}
|
}
|
||||||
log.Debug(fmt.Sprintf("adding %s (%d bytes) to new manifest", entry.Path, entry.Size))
|
log.Debug("adding path to new manifest", "ruid", req.ruid, "bytes", entry.Size, "path", entry.Path)
|
||||||
contentKey, err := mw.AddEntry(reader, entry)
|
contentKey, err := mw.AddEntry(reader, entry)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error adding manifest entry from multipart form: %s", err)
|
return fmt.Errorf("error adding manifest entry from multipart form: %s", err)
|
||||||
}
|
}
|
||||||
log.Debug(fmt.Sprintf("content for %s stored", contentKey.Log()))
|
log.Debug("stored content", "ruid", req.ruid, "key", contentKey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) handleDirectUpload(req *Request, mw *api.ManifestWriter) error {
|
func (s *Server) handleDirectUpload(req *Request, mw *api.ManifestWriter) error {
|
||||||
|
log.Debug("handle.direct.upload", "ruid", req.ruid)
|
||||||
key, err := mw.AddEntry(req.Body, &api.ManifestEntry{
|
key, err := mw.AddEntry(req.Body, &api.ManifestEntry{
|
||||||
Path: req.uri.Path,
|
Path: req.uri.Path,
|
||||||
ContentType: req.Header.Get("Content-Type"),
|
ContentType: req.Header.Get("Content-Type"),
|
||||||
|
|
@ -303,7 +315,7 @@ func (s *Server) handleDirectUpload(req *Request, mw *api.ManifestWriter) error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Debug(fmt.Sprintf("content for %s stored", key.Log()))
|
log.Debug("stored content", "ruid", req.ruid, "key", key)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -311,6 +323,8 @@ func (s *Server) handleDirectUpload(req *Request, mw *api.ManifestWriter) error
|
||||||
// <path> from <manifest> and returns the resulting manifest hash as a
|
// <path> from <manifest> and returns the resulting manifest hash as a
|
||||||
// text/plain response
|
// text/plain response
|
||||||
func (s *Server) HandleDelete(w http.ResponseWriter, r *Request) {
|
func (s *Server) HandleDelete(w http.ResponseWriter, r *Request) {
|
||||||
|
log.Debug("handle.delete", "ruid", r.ruid)
|
||||||
|
|
||||||
deleteCount.Inc(1)
|
deleteCount.Inc(1)
|
||||||
key, err := s.api.Resolve(r.uri)
|
key, err := s.api.Resolve(r.uri)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -335,6 +349,8 @@ func (s *Server) HandleDelete(w http.ResponseWriter, r *Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) HandlePostResource(w http.ResponseWriter, r *Request) {
|
func (s *Server) HandlePostResource(w http.ResponseWriter, r *Request) {
|
||||||
|
log.Debug("handle.post.resource", "ruid", r.ruid)
|
||||||
|
|
||||||
var outdata []byte
|
var outdata []byte
|
||||||
if r.uri.Path != "" {
|
if r.uri.Path != "" {
|
||||||
frequency, err := strconv.ParseUint(r.uri.Path, 10, 64)
|
frequency, err := strconv.ParseUint(r.uri.Path, 10, 64)
|
||||||
|
|
@ -398,6 +414,7 @@ func (s *Server) HandleGetResource(w http.ResponseWriter, r *Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) handleGetResource(w http.ResponseWriter, r *Request, name string) {
|
func (s *Server) handleGetResource(w http.ResponseWriter, r *Request, name string) {
|
||||||
|
log.Debug("handle.get.resource", "ruid", r.ruid)
|
||||||
var params []string
|
var params []string
|
||||||
if len(r.uri.Path) > 0 {
|
if len(r.uri.Path) > 0 {
|
||||||
params = strings.Split(r.uri.Path, "/")
|
params = strings.Split(r.uri.Path, "/")
|
||||||
|
|
@ -470,6 +487,7 @@ func (s *Server) translateResourceError(w http.ResponseWriter, r *Request, supEr
|
||||||
// - bzz-hash://<key> and responds with the hash of the content stored
|
// - bzz-hash://<key> and responds with the hash of the content stored
|
||||||
// at the given storage key as a text/plain response
|
// at the given storage key as a text/plain response
|
||||||
func (s *Server) HandleGet(w http.ResponseWriter, r *Request) {
|
func (s *Server) HandleGet(w http.ResponseWriter, r *Request) {
|
||||||
|
log.Debug("handle.get", "ruid", r.ruid, "uri", r.uri)
|
||||||
getCount.Inc(1)
|
getCount.Inc(1)
|
||||||
key, err := s.api.Resolve(r.uri)
|
key, err := s.api.Resolve(r.uri)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -477,6 +495,7 @@ func (s *Server) HandleGet(w http.ResponseWriter, r *Request) {
|
||||||
Respond(w, r, fmt.Sprintf("cannot resolve %s: %s", r.uri.Addr, err), http.StatusNotFound)
|
Respond(w, r, fmt.Sprintf("cannot resolve %s: %s", r.uri.Addr, err), http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
log.Debug("handle.get: resolved", "ruid", r.ruid, "key", key)
|
||||||
|
|
||||||
// if path is set, interpret <key> as a manifest and return the
|
// if path is set, interpret <key> as a manifest and return the
|
||||||
// raw entry at the given path
|
// raw entry at the given path
|
||||||
|
|
@ -548,6 +567,7 @@ func (s *Server) HandleGet(w http.ResponseWriter, r *Request) {
|
||||||
// header of "application/x-tar" and returns a tar stream of all files
|
// header of "application/x-tar" and returns a tar stream of all files
|
||||||
// contained in the manifest
|
// contained in the manifest
|
||||||
func (s *Server) HandleGetFiles(w http.ResponseWriter, r *Request) {
|
func (s *Server) HandleGetFiles(w http.ResponseWriter, r *Request) {
|
||||||
|
log.Debug("handle.get.files", "ruid", r.ruid, "uri", r.uri)
|
||||||
getFilesCount.Inc(1)
|
getFilesCount.Inc(1)
|
||||||
if r.uri.Path != "" {
|
if r.uri.Path != "" {
|
||||||
getFilesFail.Inc(1)
|
getFilesFail.Inc(1)
|
||||||
|
|
@ -561,6 +581,7 @@ func (s *Server) HandleGetFiles(w http.ResponseWriter, r *Request) {
|
||||||
Respond(w, r, fmt.Sprintf("cannot resolve %s: %s", r.uri.Addr, err), http.StatusNotFound)
|
Respond(w, r, fmt.Sprintf("cannot resolve %s: %s", r.uri.Addr, err), http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
log.Debug("handle.get.files: resolved", "ruid", r.ruid, "key", key)
|
||||||
|
|
||||||
walker, err := s.api.NewManifestWalker(key, nil)
|
walker, err := s.api.NewManifestWalker(key, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -621,6 +642,7 @@ func (s *Server) HandleGetFiles(w http.ResponseWriter, r *Request) {
|
||||||
// a list of all files contained in <manifest> under <path> grouped into
|
// a list of all files contained in <manifest> under <path> grouped into
|
||||||
// common prefixes using "/" as a delimiter
|
// common prefixes using "/" as a delimiter
|
||||||
func (s *Server) HandleGetList(w http.ResponseWriter, r *Request) {
|
func (s *Server) HandleGetList(w http.ResponseWriter, r *Request) {
|
||||||
|
log.Debug("handle.get.list", "ruid", r.ruid, "uri", r.uri)
|
||||||
getListCount.Inc(1)
|
getListCount.Inc(1)
|
||||||
// ensure the root path has a trailing slash so that relative URLs work
|
// ensure the root path has a trailing slash so that relative URLs work
|
||||||
if r.uri.Path == "" && !strings.HasSuffix(r.URL.Path, "/") {
|
if r.uri.Path == "" && !strings.HasSuffix(r.URL.Path, "/") {
|
||||||
|
|
@ -634,6 +656,7 @@ func (s *Server) HandleGetList(w http.ResponseWriter, r *Request) {
|
||||||
Respond(w, r, fmt.Sprintf("cannot resolve %s: %s", r.uri.Addr, err), http.StatusNotFound)
|
Respond(w, r, fmt.Sprintf("cannot resolve %s: %s", r.uri.Addr, err), http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
log.Debug("handle.get.list: resolved", "ruid", r.ruid, "key", key)
|
||||||
|
|
||||||
list, err := s.getManifestList(key, r.uri.Path)
|
list, err := s.getManifestList(key, r.uri.Path)
|
||||||
|
|
||||||
|
|
@ -725,6 +748,7 @@ func (s *Server) getManifestList(key storage.Key, prefix string) (list api.Manif
|
||||||
// HandleGetFile handles a GET request to bzz://<manifest>/<path> and responds
|
// HandleGetFile handles a GET request to bzz://<manifest>/<path> and responds
|
||||||
// with the content of the file at <path> from the given <manifest>
|
// with the content of the file at <path> from the given <manifest>
|
||||||
func (s *Server) HandleGetFile(w http.ResponseWriter, r *Request) {
|
func (s *Server) HandleGetFile(w http.ResponseWriter, r *Request) {
|
||||||
|
log.Debug("handle.get.file", "ruid", r.ruid)
|
||||||
getFileCount.Inc(1)
|
getFileCount.Inc(1)
|
||||||
// ensure the root path has a trailing slash so that relative URLs work
|
// ensure the root path has a trailing slash so that relative URLs work
|
||||||
if r.uri.Path == "" && !strings.HasSuffix(r.URL.Path, "/") {
|
if r.uri.Path == "" && !strings.HasSuffix(r.URL.Path, "/") {
|
||||||
|
|
@ -738,6 +762,7 @@ func (s *Server) HandleGetFile(w http.ResponseWriter, r *Request) {
|
||||||
Respond(w, r, fmt.Sprintf("cannot resolve %s: %s", r.uri.Addr, err), http.StatusNotFound)
|
Respond(w, r, fmt.Sprintf("cannot resolve %s: %s", r.uri.Addr, err), http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
log.Debug("handle.get.file: resolved", "ruid", r.ruid, "key", key)
|
||||||
|
|
||||||
reader, contentType, status, err := s.api.Get(key, r.uri.Path)
|
reader, contentType, status, err := s.api.Get(key, r.uri.Path)
|
||||||
|
|
||||||
|
|
@ -788,10 +813,13 @@ func (s *Server) HandleGetFile(w http.ResponseWriter, r *Request) {
|
||||||
http.ServeContent(w, &r.Request, "", time.Now(), reader)
|
http.ServeContent(w, &r.Request, "", time.Now(), reader)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||||
req := &Request{Request: *r, ruid: uuid.New()[:8]}
|
req := &Request{Request: *r, ruid: uuid.New()[:8]}
|
||||||
requestCount.Inc(1)
|
requestCount.Inc(1)
|
||||||
log.Info("serve request", "ruid", req.ruid, "method", r.Method, "url", r.RequestURI)
|
log.Info("serving request", "ruid", req.ruid, "method", r.Method, "url", r.RequestURI)
|
||||||
|
|
||||||
|
// wrapping the ResponseWriter, so that we get the response code set by http.ServeContent
|
||||||
|
w := newLoggingResponseWriter(rw)
|
||||||
|
|
||||||
if r.RequestURI == "/" && strings.Contains(r.Header.Get("Accept"), "text/html") {
|
if r.RequestURI == "/" && strings.Contains(r.Header.Get("Accept"), "text/html") {
|
||||||
|
|
||||||
|
|
@ -869,6 +897,8 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
default:
|
default:
|
||||||
Respond(w, req, fmt.Sprintf("%s method is not supported", r.Method), http.StatusMethodNotAllowed)
|
Respond(w, req, fmt.Sprintf("%s method is not supported", r.Method), http.StatusMethodNotAllowed)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Info("served response", "ruid", req.ruid, "code", w.statusCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) updateManifest(key storage.Key, update func(mw *api.ManifestWriter) error) (storage.Key, error) {
|
func (s *Server) updateManifest(key storage.Key, update func(mw *api.ManifestWriter) error) (storage.Key, error) {
|
||||||
|
|
@ -888,3 +918,17 @@ func (s *Server) updateManifest(key storage.Key, update func(mw *api.ManifestWri
|
||||||
log.Debug(fmt.Sprintf("generated manifest %s", key))
|
log.Debug(fmt.Sprintf("generated manifest %s", key))
|
||||||
return key, nil
|
return key, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type loggingResponseWriter struct {
|
||||||
|
http.ResponseWriter
|
||||||
|
statusCode int
|
||||||
|
}
|
||||||
|
|
||||||
|
func newLoggingResponseWriter(w http.ResponseWriter) *loggingResponseWriter {
|
||||||
|
return &loggingResponseWriter{w, http.StatusOK}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lrw *loggingResponseWriter) WriteHeader(code int) {
|
||||||
|
lrw.statusCode = code
|
||||||
|
lrw.ResponseWriter.WriteHeader(code)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -201,10 +201,10 @@ type manifestTrieEntry struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadManifest(dpa *storage.DPA, hash storage.Key, quitC chan bool) (trie *manifestTrie, err error) { // non-recursive, subtrees are downloaded on-demand
|
func loadManifest(dpa *storage.DPA, hash storage.Key, quitC chan bool) (trie *manifestTrie, err error) { // non-recursive, subtrees are downloaded on-demand
|
||||||
|
log.Trace("manifest lookup", "key", hash)
|
||||||
log.Trace(fmt.Sprintf("manifest lookup key: '%v'.", hash.Log()))
|
|
||||||
// retrieve manifest via DPA
|
// retrieve manifest via DPA
|
||||||
manifestReader := dpa.Retrieve(hash)
|
manifestReader := dpa.Retrieve(hash)
|
||||||
|
log.Trace("reader retrieved", "key", hash)
|
||||||
return readManifest(manifestReader, hash, dpa, quitC)
|
return readManifest(manifestReader, hash, dpa, quitC)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -214,31 +214,32 @@ func readManifest(manifestReader storage.LazySectionReader, hash storage.Key, dp
|
||||||
size, err := manifestReader.Size(quitC)
|
size, err := manifestReader.Size(quitC)
|
||||||
if err != nil { // size == 0
|
if err != nil { // size == 0
|
||||||
// can't determine size means we don't have the root chunk
|
// can't determine size means we don't have the root chunk
|
||||||
|
log.Trace("manifest not found", "key", hash)
|
||||||
err = fmt.Errorf("Manifest not Found")
|
err = fmt.Errorf("Manifest not Found")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
manifestData := make([]byte, size)
|
manifestData := make([]byte, size)
|
||||||
read, err := manifestReader.Read(manifestData)
|
read, err := manifestReader.Read(manifestData)
|
||||||
if int64(read) < size {
|
if int64(read) < size {
|
||||||
log.Trace(fmt.Sprintf("Manifest %v not found.", hash.Log()))
|
log.Trace("manifest not found", "key", hash)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = fmt.Errorf("Manifest retrieval cut short: read %v, expect %v", read, size)
|
err = fmt.Errorf("Manifest retrieval cut short: read %v, expect %v", read, size)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Trace(fmt.Sprintf("Manifest %v retrieved", hash.Log()))
|
log.Trace("manifest retrieved", "key", hash)
|
||||||
var man struct {
|
var man struct {
|
||||||
Entries []*manifestTrieEntry `json:"entries"`
|
Entries []*manifestTrieEntry `json:"entries"`
|
||||||
}
|
}
|
||||||
err = json.Unmarshal(manifestData, &man)
|
err = json.Unmarshal(manifestData, &man)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("Manifest %v is malformed: %v", hash.Log(), err)
|
err = fmt.Errorf("Manifest %v is malformed: %v", hash.Log(), err)
|
||||||
log.Trace(fmt.Sprintf("%v", err))
|
log.Trace("malformed manifest", "key", hash)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Trace(fmt.Sprintf("Manifest %v has %d entries.", hash.Log(), len(man.Entries)))
|
log.Trace("manifest entries", "key", hash, "len", len(man.Entries))
|
||||||
|
|
||||||
trie = &manifestTrie{
|
trie = &manifestTrie{
|
||||||
dpa: dpa,
|
dpa: dpa,
|
||||||
|
|
@ -435,7 +436,6 @@ func (self *manifestTrie) listWithPrefix(prefix string, quitC chan bool, cb func
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *manifestTrie) findPrefixOf(path string, quitC chan bool) (entry *manifestTrieEntry, pos int) {
|
func (self *manifestTrie) findPrefixOf(path string, quitC chan bool) (entry *manifestTrieEntry, pos int) {
|
||||||
|
|
||||||
log.Trace(fmt.Sprintf("findPrefixOf(%s)", path))
|
log.Trace(fmt.Sprintf("findPrefixOf(%s)", path))
|
||||||
|
|
||||||
if len(path) == 0 {
|
if len(path) == 0 {
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ package storage
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/metrics"
|
"github.com/ethereum/go-ethereum/metrics"
|
||||||
|
|
@ -252,6 +253,8 @@ func (s *MemStore) Get(hash Key) (chunk *Chunk, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MemStore) removeOldest() {
|
func (s *MemStore) removeOldest() {
|
||||||
|
defer metrics.GetOrRegisterResettingTimer("memstore.purge", metrics.DefaultRegistry).UpdateSince(time.Now())
|
||||||
|
|
||||||
node := s.memtree
|
node := s.memtree
|
||||||
log.Warn("purge memstore")
|
log.Warn("purge memstore")
|
||||||
for node.entry == nil {
|
for node.entry == nil {
|
||||||
|
|
|
||||||
|
|
@ -169,7 +169,7 @@ func (self *PyramidChunker) decrementWorkerCount() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *PyramidChunker) Split(data io.Reader, size int64, chunkC chan *Chunk) (k Key, wait func(), err error) {
|
func (self *PyramidChunker) Split(data io.Reader, size int64, chunkC chan *Chunk) (k Key, wait func(), err error) {
|
||||||
log.Trace("pyramid.chunker: Split()")
|
log.Debug("pyramid.chunker: Split()", "size", size)
|
||||||
jobC := make(chan *chunkJob, 2*ChunkProcessors)
|
jobC := make(chan *chunkJob, 2*ChunkProcessors)
|
||||||
wg := &sync.WaitGroup{}
|
wg := &sync.WaitGroup{}
|
||||||
storageWG := &sync.WaitGroup{}
|
storageWG := &sync.WaitGroup{}
|
||||||
|
|
@ -204,11 +204,10 @@ func (self *PyramidChunker) Split(data io.Reader, size int64, chunkC chan *Chunk
|
||||||
case <-time.NewTimer(splitTimeout).C:
|
case <-time.NewTimer(splitTimeout).C:
|
||||||
}
|
}
|
||||||
return rootKey, storageWG.Wait, nil
|
return rootKey, storageWG.Wait, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *PyramidChunker) Append(key Key, data io.Reader, chunkC chan *Chunk) (k Key, wait func(), err error) {
|
func (self *PyramidChunker) Append(key Key, data io.Reader, chunkC chan *Chunk) (k Key, wait func(), err error) {
|
||||||
log.Trace("pyramid.chunker: Append()")
|
log.Debug("pyramid.chunker: Append()")
|
||||||
quitC := make(chan bool)
|
quitC := make(chan bool)
|
||||||
rootKey := make([]byte, self.hashSize)
|
rootKey := make([]byte, self.hashSize)
|
||||||
chunkLevel := make([][]*TreeEntry, self.branches)
|
chunkLevel := make([][]*TreeEntry, self.branches)
|
||||||
|
|
@ -267,7 +266,7 @@ func (self *PyramidChunker) processor(id int64, jobC chan *chunkJob, chunkC chan
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *PyramidChunker) processChunk(id int64, hasher SwarmHash, job *chunkJob, chunkC chan *Chunk, storageWG *sync.WaitGroup) {
|
func (self *PyramidChunker) processChunk(id int64, hasher SwarmHash, job *chunkJob, chunkC chan *Chunk, storageWG *sync.WaitGroup) {
|
||||||
log.Trace("pyramid.chunker: processChunk()", "id", id)
|
log.Debug("pyramid.chunker: processChunk()", "id", id)
|
||||||
|
|
||||||
hasher.ResetWithLength(job.chunk[:8]) // 8 bytes of length
|
hasher.ResetWithLength(job.chunk[:8]) // 8 bytes of length
|
||||||
hasher.Write(job.chunk[8:]) // minus 8 []byte length
|
hasher.Write(job.chunk[8:]) // minus 8 []byte length
|
||||||
|
|
@ -294,7 +293,7 @@ func (self *PyramidChunker) processChunk(id int64, hasher SwarmHash, job *chunkJ
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *PyramidChunker) loadTree(chunkLevel [][]*TreeEntry, key Key, chunkC chan *Chunk, quitC chan bool) error {
|
func (self *PyramidChunker) loadTree(chunkLevel [][]*TreeEntry, key Key, chunkC chan *Chunk, quitC chan bool) error {
|
||||||
log.Trace("pyramid.chunker: loadTree()")
|
log.Debug("pyramid.chunker: loadTree()")
|
||||||
// Get the root chunk to get the total size
|
// Get the root chunk to get the total size
|
||||||
chunk := retrieve(key, chunkC, quitC)
|
chunk := retrieve(key, chunkC, quitC)
|
||||||
if chunk == nil {
|
if chunk == nil {
|
||||||
|
|
@ -377,7 +376,7 @@ func (self *PyramidChunker) loadTree(chunkLevel [][]*TreeEntry, key Key, chunkC
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *PyramidChunker) prepareChunks(isAppend bool, chunkLevel [][]*TreeEntry, data io.Reader, rootKey []byte, quitC chan bool, wg *sync.WaitGroup, jobC chan *chunkJob, chunkC chan *Chunk, errC chan error, storageWG *sync.WaitGroup) {
|
func (self *PyramidChunker) prepareChunks(isAppend bool, chunkLevel [][]*TreeEntry, data io.Reader, rootKey []byte, quitC chan bool, wg *sync.WaitGroup, jobC chan *chunkJob, chunkC chan *Chunk, errC chan error, storageWG *sync.WaitGroup) {
|
||||||
log.Trace("pyramid.chunker: prepareChunks", "isAppend", isAppend)
|
log.Debug("pyramid.chunker: prepareChunks", "isAppend", isAppend)
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
|
||||||
chunkWG := &sync.WaitGroup{}
|
chunkWG := &sync.WaitGroup{}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue