func doPage(db *couch.Database, p *wikiparse.Page) { defer wg.Done() a := article{} gl, err := wikiparse.ParseCoords(p.Revisions[0].Text) if err == nil { a.Geo = &geo{Type: "Feature"} a.Geo.Geometry.Type = "Point" a.Geo.Geometry.Coordinates = []float64{gl.Lon, gl.Lat} } a.RevInfo.ID = p.Revisions[0].ID a.RevInfo.Timestamp = p.Revisions[0].Timestamp a.RevInfo.Contributor = p.Revisions[0].Contributor.Username a.RevInfo.ContributorID = p.Revisions[0].Contributor.ID a.RevInfo.Comment = p.Revisions[0].Comment a.Text = p.Revisions[0].Text a.ID = escapeTitle(p.Title) a.Files = wikiparse.FindFiles(a.Text) a.Links = wikiparse.FindLinks(a.Text) _, _, err = db.Insert(&a) switch { case err == nil: // yay case httputil.IsHTTPStatus(err, 409): resolveConflict(db, &a) default: log.Printf("Error inserting %#v: %v", a, err) } }
// Generic cas update // // The first return value will be true when it was updated due to calling this method, // or false if it was already in that state or put in that state by something else // during the update attempt. // // If any errors occur while trying to update, they will be returned in the second // return value. func casUpdate(db couch.Database, thing2update interface{}, updater casUpdater, doneMetric casDoneMetric, refresh casRefresh) (bool, error) { if doneMetric(thing2update) == true { logg.LogTo("ELASTIC_THOUGHT", "No update needed: %+v, ignoring", thing2update) return false, nil } for { updater(thing2update) logg.LogTo("ELASTIC_THOUGHT", "Attempting to save update: %+v", thing2update) _, err := db.Edit(thing2update) if err != nil { // if it failed with any other error than 409, return an error if !httputil.IsHTTPStatus(err, 409) { logg.LogTo("ELASTIC_THOUGHT", "Update failed with non-409 error: %v", err) return false, err } logg.LogTo("ELASTIC_THOUGHT", "Could not update, going to refresh") // get the latest version of the document if err := refresh(thing2update); err != nil { return false, err } // does it already have the new the state (eg, someone else set it)? if doneMetric(thing2update) == true { logg.LogTo("ELASTIC_THOUGHT", "No update needed: %+v, done", thing2update) return false, nil } // no, so try updating state and saving again continue } // successfully saved, we are done logg.LogTo("ELASTIC_THOUGHT", "Successfully updated %+v, done", thing2update) return true, nil } }