Hi,
Not sure of how close this is to the original question, but with regards to passing through authentication information and similar data, my strategy has been to load all such data in a wrapper, then call the page handlers from there, similar to what James has mentioned.
in my main function for example, my page handlers are wrapped by initWrapper.
http.HandleFunc("/", initWrapper(pages.IndexPageHandler))
then in the initWrapper function, I load user information and system messages, and perform any other global type checks and functions; following which, I pass the user information to the page hanlder.
func initWrapper(pageHandleFunction SystemHandleFnc) HandleFnc {
return func(writer http.ResponseWriter, request *http.Request) {
// Handle any errors
defer func() {
if x:= recover(); x != nil {
log.Printf("[%v] caught pnic: %v", request.RemoteAddr, x)
}
}()
// Authenticate user
var cookie *http.Cookie
var err error
// Does a user have a cookie
if cookie, err = request.Cookie("
www.site.com"); err != nil{
// Send the user to the login page
http.Redirect(writer, request, "/login.html", http.StatusFound)
return
}
var loginInfo pages.LoginInfo
// Is the cookie valid
if loginInfo, err = pages.AuthenticateCookie(cookie.Value); err != nil {
// Return to the login page
http.Redirect(writer, request, "/login.html", http.StatusFound)
} else {
// Check for any system messages
var message *pages.SysMessage
if message, err = pages.CheckForMessages(loginInfo.UserDetail.UserID); err != nil {
message.Class = "error"
message.Code = 50
message.Message = err.Error()
}
...
// Return page
pageHandleFunction(writer, request, &loginInfo, message)
}
To facilitate the updating of login information, as well as it being accessed and written to by different systems, the login information is kept in memcached, and can be accessed and updated through a global function too, in the event that a "lower" level needs to modify it. Thus far, that only occurs in the account editing page, where user would modifiy their username / password etc. But this is the mechanism I use so as to pass my user information to any lower levels.
Regarding layering functionality, as seems to be the second part of the first question, my thinking is not to use "layers" as such, but different (sub) systems. Right now, to achieve the interoperability, I'm using either memcached once again, where the subsystem would pull data items off of a queue; or web service calls, in which system A directly calls subsystem B. For example, with regards to logging I'm using a memcahced implementation, in which a logRequest{RequestID} is added to a "requests" item in memcache, and then the logging subsystem, a different execuable, pulls it off, pulls the logRequest specific info, and then logs it appropriately. My notifications subsystem works with soap calls, and when something takes place that would like someone to be notified, it calls a webservice with appropriate data to do so. My intention is to rewrite this so as to use ZeroMQ in the near future, but thus far, this has been my take on layered functionality.
Quinlan