yaokai1117tiny up3e609ba11 years agoHistory
171 lines · 3.9 KB · Brainfuck
RawDownload
##########################################	The implemention of DFSNodeServer.#	DFSNodeServer is the service interface that the DFS data node can provide to DFSClient.#	Every data node in dfs use dfsnodeserver to transport file chunks and communicate with master.#	DFSNodeServer announce a Connection,#	listen the message from other computing equipment,#	and do appropriate operation,such as read, write, delete or lineoffset the DFSChunk.##	@author Yang Fan(fyabc) ######################################### implement DFSNodeServer; include "sys.m";include "draw.m";include "bufio.m"; include "dfsutil.m";include "dfsclient.m";  Connection : import sys; DFSFile : import dfsutil;DFSChunk : import dfsutil;DFSNode : import dfsutil;FD : import sys;Iobuf : import bufio; sys : Sys;bufio : Bufio;dfsutil : DFSUtil;dfsclient : DFSClient; dataPath := string "/appl/MR/ser/";homePath := string "/appl/MR/";localPort := int 2334;chunkNumber := int 0;  DFSNodeServer : module {	init : fn(ctxt : ref Draw->Context, args : list of string);}; init(ctxt : ref Draw->Context, args : list of string){	sys = load Sys Sys->PATH;	bufio = load Bufio Bufio->PATH;	dfsutil = load DFSUtil DFSUtil->PATH;	dfsclient = load DFSClient DFSClient->PATH; 	dfsutil->init(); 	buffer := bufio->open("/appl/MR/config", Bufio->OREAD);	buffer.gets('\n');	localAddr := buffer.gets('\n');	localAddr = localAddr[:len localAddr - 1]; 	spawn heartBeat(localAddr); 	(n, conn) := sys->announce("tcp!*!" + string localPort);	if (n < 0) {		sys->print("DFSServer: announce failed %r\n");		exit;	}	while(1) {		listen(conn, ctxt);	}} heartBeat(localAddr : string) {	while (1) {		dfsclient->init();		dfsclient->updateNode(localAddr, localPort, chunkNumber); 		dfsclient->disconnect();		sys->sleep(30000);	}} listen(conn : Connection, ctxt : ref Draw->Context) {	buf := array [sys->ATOMICIO] of byte;	(ok, c) := sys->listen(conn);	if (ok < 0) {		sys->print("DFSSlaveServer: listen failed %r\n");	    exit;	}	rdf := sys->open(conn.dir + "/remote", sys->OREAD);	n := sys->read(rdf, buf, len buf);	connHandle(c, ctxt);} connHandle(conn : Connection, ctxt : ref Draw->Context){	addr := array [sys->ATOMICIO] of byte;	msgStr := array [sys->ATOMICIO] of byte;	msg : list of string;		rdfd := sys->open(conn.dir + "/data", sys->OREAD);	wdfd := sys->open(conn.dir + "/data", sys->OWRITE);	rfd := sys->open(conn.dir + "/remote", sys->OREAD); 	addrlen := sys->read(rfd, addr, len addr);	sys->print("Message from: %s\n", string addr[:addrlen]); 	msglen := sys->read(rdfd, msgStr, len msgStr);	receive : while (msglen > 0) {		(nil, msg) = sys->tokenize(string msgStr[:msglen], "@");		op := hd msg;		msg = tl msg;		case (op)		{			"disconnect" => break receive;			"read" => {				chunkId := int hd msg; 				datafd := sys->open(dataPath + string chunkId, Sys->OREAD); 				if(datafd != nil)					sendReadData(datafd, chunkId, conn); 				break receive;			}						"write" => {				dfd := sys->open(conn.dir + "/data", sys->ORDWR);				sys->fprint(dfd, "start");				sys->export(dfd, dataPath, Sys->EXPWAIT);					chunkNumber++;				break receive;			}						"delete" => {				chunkId := hd msg;				ok := sys->remove(dataPath + chunkId);					sys->fprint(wdfd, "%d", ok);					chunkNumber--;			}						"lineos" => {			}						"lineosc" =>{			}			* =>				sys->fprint(wdfd, "Unknown message!\n");		}		msglen = sys->read(rdfd, msgStr, len msgStr);	} } sendReadData(datafd : ref FD, chunkId : int, conn : Connection){	dfd := sys->open(conn.dir + "/data", sys->ORDWR);	sys->mount(dfd, nil, dataPath + "remote",Sys->MCREATE, nil);	datacopyfd := sys->create(dataPath + "remote/" + string chunkId, sys->ORDWR, 8r600); 	buf := array [Sys->ATOMICIO] of byte;	length : int;	do {		length = sys->read(datafd, buf, len buf);		sys->write(datacopyfd, buf[:length], length);	}while (length == len buf); 	sys->unmount(nil, dataPath + "remote");}