Commit a0f563bf authored by Iskandar Setiadi's avatar Iskandar Setiadi
Browse files

Update tracker

parent fce71887
......@@ -37,4 +37,22 @@ Set the following lines to ```/etc/profile```:
## How to Run
- In release environment, please use ```nohup go run main.go & > my.log 2>&1&``` for running tracker process in background. After that, use ```echo $! > save_pid.txt``` to get Process ID.
Initially, we will build our Go program using ```go build main.go```.
For maintaining our process to keep running in the presence of failure, we'll use Monit 5.5 with the following configuration in ```etc/monit.conf``` (we use ```freedomofkeima``` as non-root user to run this program):
```
### Monitor Sister Tracker
check process sistertracker with pidfile /home/path-to-file/run.pid
start program = "/bin/bash -c 'cd /home/path-to-file; sudo -u freedomofkeima nohup ./main >> my.log 2>&1 & echo $! > run.pid'" with timeout 5 seconds
stop program ="/usr/bin/pkill -TERM -P `cat /home/path-to-file/run.pid`"
```
After that, you can simply use ```service monit start``` to start Monit.
## Additional Information
- Developer note: On release (32.46), use account 'freedomofkeima' for MySQL username and '167.205.32.46' for IP address.
Last Updated: April 24, 2015
......@@ -53,11 +53,13 @@ type MessageOutJSON struct {
}
var db *sql.DB // database global_variable
var db_mux = &sync.Mutex{} // global mutex for database
var ip_address string // current IP address
var current_port int // current Port
/** Insert data to DB */
func InsertData(conn net.Conn, ip uint32, port int) {
db_mux.Lock()
_, err := db.Query("INSERT IGNORE INTO client_info(ip, port) VALUES(?, ?)", ip, port)
if err != nil {
if conn != nil {
......@@ -66,20 +68,25 @@ func InsertData(conn net.Conn, ip uint32, port int) {
fmt.Println(err.Error())
}
}
db_mux.Unlock()
}
func DeleteData(ip uint32, port int) {
db_mux.Lock()
_, err := db.Query("DELETE FROM client_info WHERE ip=? AND port=?", ip, port)
if err != nil {
fmt.Println(err.Error())
}
db_mux.Unlock()
}
/** Retrieve all available clients from DB */
func RetrieveData(conn net.Conn, code int) string { // code 0 = inbound; 1 = outbound
db_mux.Lock()
rows, err := db.Query("SELECT * FROM client_info")
if err != nil {
RespondWithRealm(conn, errors.New("Error in database connection"))
fmt.Println(err)
}
defer rows.Close()
messageObject := new(MessageInJSON)
......@@ -94,6 +101,9 @@ func RetrieveData(conn net.Conn, code int) string { // code 0 = inbound; 1 = out
if err != nil {
RespondWithRealm(conn, errors.New("IP address is not valid"))
}
if ip_str == "167.205.32.46" && port == 8000 {
continue
}
if code == 0 {
messageObject.Value = append(messageObject.Value, LogValue{Ip: ip_str, Port: port})
} else if code == 1 {
......@@ -101,6 +111,7 @@ func RetrieveData(conn net.Conn, code int) string { // code 0 = inbound; 1 = out
}
}
db_mux.Unlock()
var encodedMessage []byte
if code == 0 {
......@@ -127,12 +138,16 @@ func HandleConnection(conn net.Conn) {
remoteAddress := conn.RemoteAddr().String() // broadcast statusServer except this address
fmt.Println("**Initiate connection with " + remoteAddress + "**")
readBuf := make([]byte, 4096)
conn.Read(readBuf) // accept JSON input from clients
_, err := conn.Read(readBuf) // accept JSON input from clients
if err != nil {
RespondWithRealm(conn, errors.New("Error in Reading Input"))
}
length := bytes.Index(readBuf, []byte{0})
// Convert []byte to map interface
var value map[string]interface{}
err := json.Unmarshal(readBuf[:length], &value)
err = json.Unmarshal(readBuf[:length], &value)
if err != nil {
RespondWithRealm(conn, errors.New("Error in JSON parsing"))
}
......@@ -168,6 +183,7 @@ func HandleConnection(conn net.Conn) {
InsertData(conn, ip_uint32, int(port_int))
var wg sync.WaitGroup
db_mux.Lock()
rows, err := db.Query("SELECT * FROM client_info")
if err != nil {
RespondWithRealm(conn, errors.New("Error in database connection"))
......@@ -185,6 +201,7 @@ func HandleConnection(conn net.Conn) {
go TimeoutCheck(ip_str + ":" + port_str, &wg)
}
}
db_mux.Unlock()
wg.Wait() // wait
port_str := strconv.Itoa(int(port_int))
go broadcastAll(ip_long + ":" + port_str) // async broadcast
......@@ -219,6 +236,7 @@ func sendServerStatus(address string, data string) {
}
func broadcastAll(address string) { // exclude requester address
// db_mux.Lock()
rows, err := db.Query("SELECT * FROM client_info")
data := RetrieveData(nil, 1)
if err != nil {
......@@ -237,13 +255,18 @@ func broadcastAll(address string) { // exclude requester address
go sendServerStatus(currentAddress, data)
}
}
err = rows.Err()
if (err != nil) {
// handle errors
}
// db_mux.Unlock()
fmt.Println("Send data: " + data)
}
func TimeoutCheck(address string, wg *sync.WaitGroup) {
defer wg.Done()
fmt.Println("Now checking " + address)
connTest, err := net.DialTimeout("tcp", address, 3 * time.Second) // 3 secs
connTest, err := net.DialTimeout("tcp", address, 2 * time.Second) // 2 secs
if err != nil {
fmt.Println("TimeoutCheck: " + err.Error())
// remove from DB
......@@ -280,13 +303,16 @@ func main() {
current_port = 8000
fmt.Println("Your address is: " + ip_address + ":" + strconv.Itoa(current_port))
/*
ip_long, err := Ip2long(ip_address)
/**
ip_long, err := Ip2long("167.205.32.46")
if err != nil {
// handle error
}
*/
db, err = sql.Open("mysql","freedomofkeima@tcp(127.0.0.1:3306)/sister_tracker")
if err != nil {
// handle error
}
*/
db, err = sql.Open("mysql","root@tcp(127.0.0.1:3306)/sister_tracker")
// InsertData(nil, ip_long, current_port) // add own IP address information
fmt.Println("**Finish Initializing**")
......@@ -312,8 +338,9 @@ func RespondWithRealm(conn net.Conn, err error) {
errorMessage := err.Error()
message := "{\"status\": \"error\", \"description\": \""+ errorMessage +"\"}"
_, err = conn.Write([]byte(message)) // send response
fmt.Println("Response: " + message)
if err != nil {
// handle error
}
conn.Close()
}
}
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment