This commit is contained in:
Liang Ding 2014-09-22 23:13:07 +08:00
parent 711f1943c9
commit 1b3ac8ad66
5 changed files with 132 additions and 15 deletions

View File

@ -17,12 +17,22 @@ import (
"github.com/golang/glog"
)
type User struct {
Name string
Password string
Workspace string // 指定了该用户的 GOPATH 路径
// 最后一次会话内容结构.
type LatestSessionContent struct {
FileTree []string // 文件树展开的路径集
Files []string // 编辑器打开的文件路径集
CurrentFile string // 当前编辑器文件路径
}
// 用户结构.
type User struct {
Name string
Password string
Workspace string // 指定了该用户的 GOPATH 路径
LatestSessionContent *LatestSessionContent
}
// 配置结构.
type conf struct {
Server string
StaticServer string
@ -37,12 +47,16 @@ type conf struct {
Users []*User
}
// 配置.
var Wide conf
// 维护非变化部分的配置.
// 只有 Users 是会运行时变化的,保存回写文件时要使用这个变量.
var rawWide conf
// 定时检查 Wide 运行环境.
// 如果是特别严重的问题(比如 $GOPATH 不存在)则退出进程,另一些不太严重的问题(比如 gocode 不存在)则放入全局通知队列.
func CheckEnv() {
func FixedTimeCheckEnv() {
go func() {
for {
if "" == os.Getenv("GOPATH") {
@ -73,6 +87,19 @@ func CheckEnv() {
}
// TODO: 7 分钟进行一次检查环境
time.Sleep(time.Second * 7)
}
}()
}
// 定时10 分钟)保存配置.
// 主要是保存用户会话内容,以备下一次用户打开 Wide 时进行会话还原.
func FixedTimeSave() {
go func() {
for {
Save()
// TODO: 10 分钟进行一次配置保存
time.Sleep(time.Second * 10)
}
}()
@ -124,7 +151,7 @@ func getGOBIN() string {
// 保存 Wide 配置.
func Save() bool {
// 只有 Users 是可以通过界面修改的,其他属性只能手工维护 wide.json 配置文件
// 只有 Users 是会运行时变化的,其他属性只能手工维护 wide.json 配置文件
rawWide.Users = Wide.Users
// 原始配置文件内容

View File

@ -13,7 +13,19 @@
{
"Name": "admin",
"Password": "admin",
"Workspace": "{pwd}/data/user_workspaces/admin"
"Workspace": "{pwd}/data/user_workspaces/admin",
"LatestSessionContent": {
"FileTree": [
"1/",
"2/"
],
"Files": [
"1.go",
"2.go",
"3.go"
],
"CurrentFile": "current file"
}
}
]
}

View File

@ -36,7 +36,10 @@ func init() {
conf.Load()
// 定时检查运行环境
conf.CheckEnv()
conf.FixedTimeCheckEnv()
// 定时保存配置
conf.FixedTimeSave()
}
// 登录.
@ -158,6 +161,7 @@ func main() {
http.HandleFunc("/login", loginHandler)
http.HandleFunc("/", indexHandler)
http.HandleFunc("/session/ws", session.WSHandler)
http.HandleFunc("/session/save", session.SaveContent)
// 运行相关
http.HandleFunc("/build", output.BuildHandler)

View File

@ -7,6 +7,7 @@
package session
import (
"encoding/json"
"math/rand"
"net/http"
"os"
@ -14,6 +15,7 @@ import (
"sync"
"time"
"github.com/b3log/wide/conf"
"github.com/b3log/wide/event"
"github.com/b3log/wide/util"
"github.com/golang/glog"
@ -42,13 +44,15 @@ var HTTPSession = sessions.NewCookieStore([]byte("BEYOND"))
// Wide 会话,对应一个浏览器 tab.
type WideSession struct {
Id string // 唯一标识
HTTPSession *sessions.Session // 关联的 HTTP 会话
Processes []*os.Process // 关联的进程集
EventQueue *event.UserEventQueue // 关联的事件队列
State int // 状态
Created time.Time // 创建时间
Updated time.Time // 最近一次使用时间
Id string // 唯一标识
Username string // 用户名
HTTPSession *sessions.Session // 关联的 HTTP 会话
Processes []*os.Process // 关联的进程集
EventQueue *event.UserEventQueue // 关联的事件队列
State int // 状态
Content *conf.LatestSessionContent // 最近一次会话内容
Created time.Time // 创建时间
Updated time.Time // 最近一次使用时间
}
type Sessions []*WideSession
@ -133,6 +137,56 @@ func WSHandler(w http.ResponseWriter, r *http.Request) {
}
}
// 会话内容保存.
func SaveContent(w http.ResponseWriter, r *http.Request) {
data := map[string]interface{}{"succ": true}
defer util.RetJSON(w, r, data)
var args map[string]interface{}
if err := json.NewDecoder(r.Body).Decode(&args); err != nil {
glog.Error(err)
data["succ"] = false
return
}
sid := args["sid"].(string)
wSession := WideSessions.Get(sid)
if nil == wSession {
data["succ"] = false
return
}
wSession.Content.CurrentFile = args["currentFile"].(string)
// TODO: Ugly
fileTree := args["fileTree"].([]interface{})
ft := []string{}
for _, v := range fileTree {
ft = append(ft, v.(string))
}
wSession.Content.FileTree = ft
files := args["files"].([]interface{})
fs := []string{}
for _, v := range files {
fs = append(fs, v.(string))
}
wSession.Content.Files = fs
for _, user := range conf.Wide.Users {
if user.Name == wSession.Username {
user.LatestSessionContent = wSession.Content
// 定时任务会负责持久化
return
}
}
}
// 设置会话关联的进程集.
func (s *WideSession) SetProcesses(ps []*os.Process) {
s.Processes = ps
@ -160,9 +214,11 @@ func (sessions *Sessions) New(httpSession *sessions.Session) *WideSession {
ret := &WideSession{
Id: id,
Username: httpSession.Values["username"].(string),
HTTPSession: httpSession,
EventQueue: userEventQueue,
State: SessionStateActive,
Content: &conf.LatestSessionContent{},
Created: now,
Updated: now,
}

View File

@ -17,3 +17,21 @@ sessionWS.onerror = function (e) {
console.log('[session onerror] ' + JSON.parse(e));
};
// 定时30 秒)保存会话内容.
setTimeout(function () {
var request = newWideRequest();
// TODO: 会话状态保存
request.currentFile = "current file"; // 当前编辑器
request.fileTree = ["1/", "2/"]; // 文件树展开状态
request.files = ["1.go", "2.go", "3.go"]; // 编辑器打开状态
$.ajax({
type: 'POST',
url: '/session/save',
data: JSON.stringify(request),
dataType: "json",
success: function (data) {
}
});
}, 30000);