Clear[RootReduceServer]

Local

RootReduceServer["local"]["RootReduce"][x_List]:=((*DebugPrint["Local RootReduce"];*)(*If[Chop[N[#+π]-π]===0,0,*)lastRootReduce=#;If[$VersionNumber≥7.,RootReduce[#,Method->"Recursive"],RootReduce[#]](*]*))&/@x

RootReduceServer["local"]["FindNonZero"][x_List]:=Module[
{k=1,r=x,y,
rr=((*DebugPrint["Local RootReduce"];*)(*If[Chop[N[#+π]-π]===0,0,*)If[$VersionNumber≥7.,RootReduce[#,Method->"Recursive"],RootReduce[#]](*]*))&},
While[k≤Length[r]∧(r[[k]]=rr[r[[k]]])===0,
++k
];
++k;
While[k≤Length[r],
r[[k]]=$Failed;
++k
];
r
]

Echo[x_]:=(Print[x];x)

Numeric

RootReduceServer["numeric",proxy_RootReduceServer][operation:"RootReduce"|"FindNonZero"][x_List]:=
Module[{results,positions},
results=Replace[x,y_/;(Chop[N[y+π]-π]===0)->0,1];
positions=Flatten[Position[results,Except[0],1,Heads->False]];
results[[positions]]=proxy[operation][results[[positions]]];
results
]

Chunker

RootReduceServer["chunker",proxy_RootReduceServer][operation:"RootReduce"|"FindNonZero"][{}]:={}

RootReduceServer["chunker",proxy_RootReduceServer][operation:"RootReduce"|"FindNonZero"][x_List]/;Length[x]>0:=With[{byteLimit=40000},
Module[{heads,lengths,pieces,results,positions,secondPassResults},
{heads,lengths,pieces}=Transpose[If[MatchQ[Head[#],Plus|Times]∧Length[#]>1∧ByteCount[#]>byteLimit,
{Head[#],Length[#],List@@#},
{Sequence,1,{#}}
]&/@x];
DebugPrint["chunking... (",Length[x],")"];
results=chunk[proxy["RootReduce"][Join@@pieces],lengths];
If[!MatchQ[results,l_List/;Length[l]==Length[heads]],
DebugPrint["Chunker proxy failed."];
Return[Table[$Failed,{Length[x]}]];
];
results=results/.list_/;MemberQ[list,$Failed]:>{$Failed};
positions=Flatten[Position[results,list_List/;Length[list]>1,1,Heads->False]];
results=#[[1]]@@#[[2]]&/@Transpose[{heads,results}];
DebugPrint["assembling chunks... (",Length[positions],")"];
secondPassResults=proxy[operation][results[[positions]]];
results[[positions]]=secondPassResults;
DebugPrint["done chunking..."];
results
]
]

chunk[list_List,lengths_List]:=list[[#]]&/@With[{partialSums=FoldList[Plus,0,lengths]},Span@@#&/@Transpose[{1+Most[partialSums],Rest[partialSums]}]]

Database

Needs["DatabaseLink`"];Needs["JLink`"];

(*SQLExecute[OpenSQLConnection[JDBC["mysql","mysql.tqft.net/fusionatlas"],"Username"->"fusion","Password"->"fusion"], 
"CREATE TABLE RootReduce (expression TEXT NOT NULL,  result TEXT)"];*)

SQLConnections={};

RootReduceDatabase[url_String,user_String,pass_String]["getConnection"]:=Module[{connections,badConnections,result},
(*DebugPrint["Beginning getConnection."];*)
connections=Cases[SQLConnections,({url,user,pass}->connection_):>connection];
(*DebugPrint["Found ",Length[connections]," cached SQL connections."];*)
badConnections=Cases[connections,connection_/;!JavaObjectQ[connection[[2]]]∨connection[[2]]@isClosed[]];
(*DebugPrint["Of those ",Length[badConnections]," seem to be broken."];*)
SQLConnections=DeleteCases[SQLConnections,_->Alternatives@@badConnections];
connections=Complement[connections,badConnections];
If[Length[connections]==0,
If[Length[SQLConnections]>4,
CloseSQLConnection/@(Last/@Drop[SQLConnections,4]);
SQLConnections=Take[SQLConnections,4];
];
DebugPrint["Creating a new SQL connection."];
result=OpenSQLConnection[JDBC["mysql",url],"Username"->user,"Password"->pass, "UseConnectionPool" -> True];
SQLConnections=SQLConnections~Join~{{url,user,pass}->result};,
result=First[connections];
];
(*DebugPrint["Finished getConnection."];*)
result
]

RootReduceServer[_RootReduceDatabase]["RootReduce"|"FindNonZero"][{}]:={}

$RootReduceDatabaseRowLimit=1000;

RootReduceServer[db_RootReduceDatabase]["RootReduce"][x_List]/;Length[x]>$RootReduceDatabaseRowLimit:=Join@@(RootReduceServer[db]["RootReduce"]/@Partition[x,$RootReduceDatabaseRowLimit,$RootReduceDatabaseRowLimit,{1,1},{}])

RootReduceServer[db_RootReduceDatabase]["FindNonZero"][x_List]/;Length[x]>$RootReduceDatabaseRowLimit:=
Module[{k,pieces=Partition[x,$RootReduceDatabaseRowLimit,$RootReduceDatabaseRowLimit,{1,1},{}],result,results={}},
Do[
result=RootReduceServer[db]["FindNonZero"][pieces[[k]]];
results=results~Join~result;
If[MemberQ[result,Except[0|$Failed]],
Return[PadRight[results,Length[x],$Failed]];
]
,{k,1,Length[pieces]}];
result
]

RootReduceServer[db_RootReduceDatabase]["RootReduce"|"FindNonZero"][x_List]/;0<Length[x]≤$RootReduceDatabaseRowLimit:=
Module[{conn,pairs,results,rules},
DebugPrint["Database lookup (",Length[x],")"];
conn=db["getConnection"];
DebugPrint[conn];
If[conn===$Failed,
DebugPrint["Database connection failed!"];
Return[Table[$Failed,{Length[x]}]];
];
pairs={#,ToString[#,InputForm]}&/@x;
results=TimeConstrained[SQLSelect[conn,"RootReduce",{"expression","result"},SQLMemberQ[Last/@pairs,SQLColumn["expression"]]],∞];
If[results===$Failed∨results===$Aborted,
DebugPrint["Database lookup failed!"];
Return[Table[$Failed,{Length[x]}]];
];
DebugPrint["Database lookup finished."];
rules=results/.{e_String,r_String}:>({_,e}->ToExpression[r]);
(pairs/.rules)/.{_,_String}:>$Failed
]

RootReduceServer[db_RootReduceDatabase,proxy_RootReduceServer][op:"RootReduce"|"FindNonZero"][x_List]:=
Module[{dbResults,dbPairs,unknowns,proxyResults,proxyPairs,toInsert,chunks,proxyRules},
(* First, look up what we can in the database *)
dbResults=RootReduceServer[db][op][x];
If[op==="FindNonZero"∧MemberQ[dbResults,Except[0|$Failed]],Return[dbResults]];
If[!MatchQ[dbResults,l_List/;Length[l]==Length[x]],
DebugPrint["Database lookup failed."];
Return[Table[$Failed,{Length[x]}]];
];
dbPairs=Transpose[{x,dbResults}];
(*DebugPrint["Database lookup returned: ",dbPairs];*)
unknowns=Cases[dbPairs,{e_,$Failed}:>e];
(* Now ask the proxy *)
If[Length[unknowns]>0,
proxyResults=proxy[op][unknowns];,
proxyResults={};
];
If[!MatchQ[proxyResults,l_List/;Length[l]==Length[unknowns]],
DebugPrint["Database proxy failed."];
Return[dbResults];
];
proxyPairs=Transpose[{unknowns,proxyResults}];
(*DebugPrint["Proxy returned: ",proxyPairs];*)
(* Now write stuff back into the database *)
toInsert=Cases[proxyPairs,{e_,r:Except[$Failed]}:>{ToString[e,InputForm],ToString[r,InputForm]}];
If[Length[toInsert]>0,
DebugPrint["Upload ",Length[toInsert]," results to the database."];
chunks=Partition[toInsert,$RootReduceDatabaseRowLimit,$RootReduceDatabaseRowLimit,{1,1},{}];
SQLInsert[db["getConnection"],"RootReduce",{"expression","result"},#]&/@chunks;
DebugPrint["Finished upload."];
];
(* Now assemble the results and return *)
proxyRules=Rule@@#&/@proxyPairs;
Last/@(dbPairs/.{e_,$Failed}:>{e,e/.proxyRules})
]

Parallel

Needs["Parallel`Preferences`"];

Needs["SubKernels`LocalKernels`"];
Needs["SubKernels`RemoteKernels`"];
Needs["SubKernels`LinkKernels`"];

LaunchAllKernels[k_:0,l_:2]:=Module[{},
Off[LinkObject::linkd, LinkObject::linkn,KernelObject::rdead];
LaunchKernels[k];
Block[{$RemoteUserName=#[[2]]},LaunchKernels[RemoteMachine[#[[1]],l]]]&/@$RemoteMachines;
On[LinkObject::linkd, LinkObject::linkn,KernelObject::rdead];
]

RootReduceServer["parallel"][op_][x_List]/;Length[Kernels[]]==0:=Module[{},
LaunchAllKernels[2];
RootReduceServer["parallel"][op][x]
]

RootReduceServer["parallel"]["RootReduce"][x_List]/;Length[Kernels[]]>0:=
Module[{result},
DebugPrint["Beginning parallel map... (",Length[x],")"];
result=ParallelMap[Function[{z},If[Chop[N[z+π]-π]===0,0,If[$VersionNumber≥7.,RootReduce[z,Method->"Recursive"],RootReduce[z]]]],x];
DebugPrint["Finished parallel map..."];
result
]

RootReduceServer["parallel"]["FindNonZero"][x_List]/;Length[Kernels[]]>0:=
Module[{results=Table[$Failed,{Length[x]}],tasks,pair,result=0,task},
With[{f=Function[{z},If[Chop[N[z[[2]]+π]-π]===0,0,{z[[1]],If[$VersionNumber≥7.,RootReduce[z[[2]],Method->"Recursive"],RootReduce[z[[2]]]]}]]},
DebugPrint["Beginning parallel FindNonZero... (",Length[x],")"];
tasks=ParallelSubmit[f[#]]&/@Transpose[{Range[Length[x]],x}];
While[result===0∧Length[tasks]>0,
{pair,task,tasks}=WaitNext[tasks];
result=results[[pair[[1]]]]=pair[[2]];
DebugPrint["Received result: ",result];
];
DebugPrint["Finished parallel FindNonZero..."];
results
]
]

$RemoteMachines={{"1.mma.tqft.net","scott"},{"2.mma.tqft.net","scmorri"}};

ParallelCheckTrue[f_,L_List]/;Length[Kernels[]]>0:=Module[{result=True,task,tasks},
tasks=ParallelSubmit[f[#]]&/@L;
While[result===True∧Length[tasks]>0,
{result,task,tasks}=WaitNext[tasks];
];
DebugPrint["Finished parallel calculation."];
result
]