Просмотр исходного кода

session manager working now. 偶也

master
Patrick Peng Sun 8 лет назад
Родитель
Сommit
2c32bdadb7
3 измененных файлов: 45 добавлений и 17 удалений
  1. +2
    -2
      main.go
  2. +10
    -2
      server.go
  3. +33
    -13
      sessionManager.go

+ 2
- 2
main.go Просмотреть файл



func startSessionManager(concurrent int) { func startSessionManager(concurrent int) {
m := SessionManager{} m := SessionManager{}
all := make(chan InWechatMsg, concurrent)
go m.startSessionManager(all)
AllInMessage = make(chan InWechatMsg, concurrent)
go m.startSessionManager(AllInMessage)
} }


func setupRootFileServer() { func setupRootFileServer() {

+ 10
- 2
server.go Просмотреть файл

"reflect" "reflect"
"sort" "sort"
"strings" "strings"
"time"
) )


//apiV1Main version 1 main entry for all wechat callbacks //apiV1Main version 1 main entry for all wechat callbacks
if !valid { if !valid {
log.Println("Error: Invalid Input ") log.Println("Error: Invalid Input ")
} }

AllInMessage <- in

openID := in.header.FromUserName openID := in.header.FromUserName
if openID == "" { if openID == "" {
log.Println("nothing") log.Println("nothing")
} }
time.Sleep(5 * time.Second)

//dummy reply
reply, _ := BuildTextMsg(openID, "澳")
w.Header().Set("Content-Type", "text/xml; charset=utf-8")
fmt.Fprint(w, reply)

//time.Sleep(5 * time.Second)
v := reflect.ValueOf(answerWechatPost) v := reflect.ValueOf(answerWechatPost)
log.Printf("Current Pointer: %d", v.Pointer()) log.Printf("Current Pointer: %d", v.Pointer())
//debug.PrintStack() //debug.PrintStack()

+ 33
- 13
sessionManager.go Просмотреть файл

// we collect them and redistribute it according to // we collect them and redistribute it according to
// openID, all messages for a single openID will be // openID, all messages for a single openID will be
// sequentially processed // sequentially processed
var AllInMessage <-chan InWechatMsg
var AllInMessage chan InWechatMsg


//a stand alone routine that manage all //a stand alone routine that manage all
// live sessions // live sessions
// for each openid, its message are manipulated in serial manner. // for each openid, its message are manipulated in serial manner.
func (m *SessionManager) startSessionManager(in <-chan InWechatMsg) { func (m *SessionManager) startSessionManager(in <-chan InWechatMsg) {
log.Println("session manager start..") log.Println("session manager start..")
m.sessions = map[string]openIDSession{}
m.done = make(chan workDone, 2000)
for { //forever looping for { //forever looping
select { select {
case msg := <-in: case msg := <-in:
} }


func (m *SessionManager) processIncomingMsg(v InWechatMsg) { func (m *SessionManager) processIncomingMsg(v InWechatMsg) {
cnt := m.addJob(v)
if cnt == 1 { //there is no worker thread working
go m.startJob(v.header.FromUserName)
}
}

func (m *SessionManager) addJob(v InWechatMsg) (jobCount int) {
openID := v.header.FromUserName openID := v.header.FromUserName
s, found := m.sessions[openID] s, found := m.sessions[openID]
if !found { //create one if !found { //create one
} }
s.jobs <- v //add job to channel s.jobs <- v //add job to channel
s.count++ s.count++
m.sessions[openID] = s

log.Printf("Incoming message in queue %d", s.count) log.Printf("Incoming message in queue %d", s.count)
if s.count == 1 { //there is no worker thread working
m.startJob(openID)
} else if s.count <= 0 {
log.Println(s)
log.Fatal("new job added, but count = 0")
log.Printf("Total Session count = %d", len(m.sessions))
if s.count <= 0 {
log.Fatal("new job added, but count <= 0")
} }
return s.count
} }


func (m *SessionManager) createSession(openID string) openIDSession { func (m *SessionManager) createSession(openID string) openIDSession {


func (m *SessionManager) clearJobDone(d workDone) { func (m *SessionManager) clearJobDone(d workDone) {
s, found := m.sessions[d.openID] s, found := m.sessions[d.openID]
log.Println(s)
if found { if found {
s.count -= d.consumed s.count -= d.consumed
if s.count == 0 { //no job to do if s.count == 0 { //no job to do
data.Save() data.Save()
//remove from memory //remove from memory
m.destroySession(d.openID) m.destroySession(d.openID)
log.Printf("destroy session %s", d.openID)
} else if s.count > 0 { } else if s.count > 0 {
m.startJob(d.openID) //processing any newly coming jobs
go m.startJob(d.openID) //processing any newly coming jobs
} else { } else {
log.Println(s) log.Println(s)
log.Fatal("session job count cannot be negative, problem session") log.Fatal("session job count cannot be negative, problem session")
close(s.jobs) close(s.jobs)
//delete it from memory //delete it from memory
delete(m.sessions, openID) delete(m.sessions, openID)
log.Printf("total session count=%d", len(m.sessions))
} }


//worker thread //worker thread
func (m *SessionManager) startJob(openID string) { func (m *SessionManager) startJob(openID string) {
log.Println("start job worker...")
s := m.sessions[openID] s := m.sessions[openID]
jobFinished := workDone{openID, 0} jobFinished := workDone{openID, 0}
//process all jobs in the channel //process all jobs in the channel
for v := range s.jobs {
log.Println(" Processing job..")
log.Println(v)
time.Sleep(5 * time.Second)
jobFinished.consumed++
hasJob := true
for hasJob {
select {
case v := <-s.jobs:
log.Println(" Processing job..")
log.Println(v)
time.Sleep(5 * time.Second)
kfSendTxt(openID, "Job Processed "+v.body.(TextMsg).Content)
jobFinished.consumed++
default:
hasJob = false
}
} }
m.done <- jobFinished //notify parent that we have done m.done <- jobFinished //notify parent that we have done
return return

Загрузка…
Отмена
Сохранить