Skip to content

Commit

Permalink
Refactor dispatch pipeline in Swift (#2269)
Browse files Browse the repository at this point in the history
  • Loading branch information
bernardnormier authored Jun 5, 2024
1 parent 6a03462 commit aaf3836
Show file tree
Hide file tree
Showing 40 changed files with 785 additions and 905 deletions.
38 changes: 11 additions & 27 deletions cpp/src/slice2swift/Gen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1437,7 +1437,7 @@ Gen::ObjectVisitor::visitInterfaceDefStart(const InterfaceDefPtr& p)
out << sp;
out << sp;
out << nl << "/// Dispatcher for `" << servant << "` servants.";
out << nl << "public struct " << disp << ": " << getUnqualified("Ice.Disp", swiftModule);
out << nl << "public struct " << disp << ": Ice.Dispatcher";
out << sb;
out << nl << "public let servant: " << servant;

Expand Down Expand Up @@ -1468,42 +1468,33 @@ Gen::ObjectVisitor::visitInterfaceDefStart(const InterfaceDefPtr& p)

out << sp;
out << nl;
out << "public func dispatch";
out << spar;
out << ("request: " + getUnqualified("Ice.Request", swiftModule));
out << ("current: " + getUnqualified("Ice.Current", swiftModule));
out << epar;
out << " throws -> PromiseKit.Promise<" << getUnqualified("Ice.OutputStream", swiftModule) << ">?";

out << "public func dispatch(_ request: Ice.IncomingRequest) -> PromiseKit.Promise<Ice.OutgoingResponse>";
out << sb;
// Call startOver() so that dispatch interceptors can retry requests
out << nl << "request.startOver()";
out << nl << "switch current.operation";
out << nl;
out << "switch request.current.operation";
out << sb;
out.dec(); // to align case with switch
for (StringList::const_iterator q = allOpNames.begin(); q != allOpNames.end(); ++q)
for (const auto& opName : allOpNames)
{
const string opName = *q;
out << nl << "case \"" << opName << "\":";
out.inc();
if (opName == "ice_id" || opName == "ice_ids" || opName == "ice_isA" || opName == "ice_ping")
{
out << nl << "return try (servant as? Object ?? " << disp << ".defaultObject)._iceD_" << opName
<< "(incoming: request, current: current)";
out << nl << "(servant as? Ice.Object ?? " << disp << ".defaultObject)._iceD_" << opName << "(request)";
}
else
{
out << nl << "return try servant._iceD_" << opName << "(incoming: request, current: current)";
out << nl << "servant._iceD_" << opName << "(request)";
}
out.dec();
}
out << nl << "default:";
out.inc();
out << nl << "throw " << getUnqualified("Ice.OperationNotExistException", swiftModule)
<< "(id: current.id, facet: current.facet, operation: current.operation)";
out << nl << "PromiseKit.Promise(error: Ice.OperationNotExistException())";
// missing dec to compensate for the extra dec after switch sb
out << eb;
out << eb;

out << eb;

//
Expand Down Expand Up @@ -1604,7 +1595,7 @@ Gen::ObjectExtVisitor::visitInterfaceDefStart(const InterfaceDefPtr& p)

out << sp;
writeServantDocSummary(out, p, swiftModule);
out << nl << "public extension " << fixIdent(name);
out << nl << "extension " << fixIdent(name);

out << sb;
return true;
Expand All @@ -1619,12 +1610,5 @@ Gen::ObjectExtVisitor::visitInterfaceDefEnd(const InterfaceDefPtr&)
void
Gen::ObjectExtVisitor::visitOperation(const OperationPtr& op)
{
if (operationIsAmd(op))
{
writeDispatchAsyncOperation(out, op);
}
else
{
writeDispatchOperation(out, op);
}
writeDispatchOperation(out, op);
}
184 changes: 71 additions & 113 deletions cpp/src/slice2swift/SwiftUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2181,8 +2181,6 @@ SwiftGenerator::writeMarshalOutParams(::IceUtilInternal::Output& out, const Oper
ParamInfoList requiredOutParams, optionalOutParams;
getOutParams(op, requiredOutParams, optionalOutParams);

out << "{ ostr in";
out.inc();
//
// Marshal parameters
// 1. required
Expand All @@ -2203,9 +2201,6 @@ SwiftGenerator::writeMarshalOutParams(::IceUtilInternal::Output& out, const Oper
{
out << nl << "ostr.writePendingValues()";
}

out.dec();
out << nl << "}";
}

void
Expand All @@ -2214,8 +2209,7 @@ SwiftGenerator::writeMarshalAsyncOutParams(::IceUtilInternal::Output& out, const
ParamInfoList requiredOutParams, optionalOutParams;
getOutParams(op, requiredOutParams, optionalOutParams);

out << sb << " (ostr, retVals) in";
out << nl << "let " << operationReturnDeclaration(op) << " = retVals";
out << nl << "let " << operationReturnDeclaration(op) << " = value";
//
// Marshal parameters
// 1. required
Expand All @@ -2236,8 +2230,6 @@ SwiftGenerator::writeMarshalAsyncOutParams(::IceUtilInternal::Output& out, const
{
out << nl << "ostr.writePendingValues()";
}

out << eb;
}

void
Expand Down Expand Up @@ -2330,8 +2322,6 @@ SwiftGenerator::writeUnmarshalInParams(::IceUtilInternal::Output& out, const Ope
// 1. required
// 3. optional
//
out << "{ istr in";
out.inc();
for (ParamInfoList::const_iterator q = requiredInParams.begin(); q != requiredInParams.end(); ++q)
{
if (q->param)
Expand Down Expand Up @@ -2369,25 +2359,6 @@ SwiftGenerator::writeUnmarshalInParams(::IceUtilInternal::Output& out, const Ope
{
out << nl << "try istr.readPendingValues()";
}

out << nl << "return ";
if (allInParams.size() > 1)
{
out << spar;
}

for (ParamInfoList::const_iterator q = allInParams.begin(); q != allInParams.end(); ++q)
{
out << ("iceP_" + q->name);
}

if (allInParams.size() > 1)
{
out << epar;
}

out.dec();
out << nl << "}";
}

void
Expand Down Expand Up @@ -2610,111 +2581,98 @@ SwiftGenerator::writeDispatchOperation(::IceUtilInternal::Output& out, const Ope
{
const string opName = op->name();

const ParamInfoList allInParams = getAllInParams(op);
const ParamInfoList allOutParams = getAllOutParams(op);
const ExceptionList allExceptions = op->throws();
const ParamInfoList inParams = getAllInParams(op);
const ParamInfoList outParams = getAllOutParams(op);

const string swiftModule = getSwiftModule(getTopLevelModule(dynamic_pointer_cast<Contained>(op)));

out << sp;
out << nl << "func _iceD_" << opName;
out << spar;
out << ("incoming inS: " + getUnqualified("Ice.Incoming", swiftModule));
out << ("current: " + getUnqualified("Ice.Current", swiftModule));
out << epar;

out << " throws -> PromiseKit.Promise<" << getUnqualified("Ice.OutputStream", swiftModule) << ">?";
out << nl << "public func _iceD_" << opName
<< "(_ request: Ice.IncomingRequest) -> PromiseKit.Promise<Ice.OutgoingResponse>";

out << sb;
if (allInParams.empty())
{
out << nl << "try inS.readEmptyParams()";
}
else
{
out << nl << "let " << operationInParamsDeclaration(op) << " = try inS.read ";
writeUnmarshalInParams(out, op);
}

if (op->format() != DefaultFormat)
{
out << nl << "inS.setFormat(" << opFormatTypeToString(op) << ")";
}

out << sp;
out << nl;
if (!allOutParams.empty())
{
out << "let " << operationReturnDeclaration(op) << " = ";
}
out << "try self." << fixIdent(opName);
out << nl << "do";
out << sb;

out << spar;
for (ParamInfoList::const_iterator q = allInParams.begin(); q != allInParams.end(); ++q)
{
out << (q->name + ": iceP_" + q->name);
}
out << "current: current";
out << epar;
// TODO: check operation mode

out << sp << nl;
out << "return inS.setResult";
if (allOutParams.empty())
if (inParams.empty())
{
out << "()";
out << nl << "_ = try request.inputStream.skipEmptyEncapsulation()";
}
else
{
writeMarshalOutParams(out, op);
out << nl << "let istr = request.inputStream";
out << nl << "_ = try istr.startEncapsulation()";
writeUnmarshalInParams(out, op);
}
out << eb;
}

void
SwiftGenerator::writeDispatchAsyncOperation(::IceUtilInternal::Output& out, const OperationPtr& op)
{
const ParamInfoList allInParams = getAllInParams(op);
const ParamInfoList allOutParams = getAllOutParams(op);

const string swiftModule = getSwiftModule(getTopLevelModule(dynamic_pointer_cast<Contained>(op)));

out << sp;
out << nl << "func _iceD_" << op->name();
out << spar;
out << ("incoming inS: " + getUnqualified("Ice.Incoming", swiftModule));
out << ("current: " + getUnqualified("Ice.Current", swiftModule));
out << epar;

out << " throws -> PromiseKit.Promise<" << getUnqualified("Ice.OutputStream", swiftModule) << ">?";
out << sb;
if (allInParams.empty())
if (operationIsAmd(op))
{
out << nl << "try inS.readEmptyParams()";
out << nl << "return self." << opName << "Async(";
out << nl << " "; // inc/dec doesn't work for an unknown reason
for (const auto& q : inParams)
{
out << q.name << ": iceP_" << q.name << ", ";
}
out << "current: request.current";
out << nl;
out << ").map(on: nil)";
out << sb;
if (outParams.empty())
{
out << nl << "request.current.makeEmptyOutgoingResponse()";
}
else
{
out << " result in ";
out << nl << "request.current.makeOutgoingResponse(result, formatType:" << opFormatTypeToString(op) << ")";
out << sb;
out << " ostr, value in ";
writeMarshalAsyncOutParams(out, op);
out << eb;
}
out << eb;
}
else
{
out << nl << "let " << operationInParamsDeclaration(op) << " = try inS.read ";
writeUnmarshalInParams(out, op);
}

if (op->format() != DefaultFormat)
{
out << nl << "inS.setFormat(" << opFormatTypeToString(op) << ")";
}
out << sp;
out << nl;
if (!outParams.empty())
{
out << "let " << operationReturnDeclaration(op) << " = ";
}
out << "try self." << fixIdent(opName);
out << spar;
for (const auto& q : inParams)
{
out << (q.name + ": iceP_" + q.name);
}
out << "current: request.current";
out << epar;

out << sp << nl;
out << "return inS.setResultPromise(" << fixIdent(op->name() + (operationIsAmd(op) ? "Async" : "")) << spar;
for (ParamInfoList::const_iterator q = allInParams.begin(); q != allInParams.end(); ++q)
{
out << (q->name + ": iceP_" + q->name);
}
out << "current: current" << epar;
out << ")";
if (!allOutParams.empty())
{
writeMarshalAsyncOutParams(out, op);
if (outParams.empty())
{
out << nl << "return PromiseKit.Promise.value(request.current.makeEmptyOutgoingResponse())";
}
else
{
out << nl << "let ostr = request.current.startReplyStream()";
out << nl
<< "ostr.startEncapsulation(encoding: request.current.encoding, format: " << opFormatTypeToString(op)
<< ")";
writeMarshalOutParams(out, op);
out << nl << "ostr.endEncapsulation()";
out << nl << "return PromiseKit.Promise.value(Ice.OutgoingResponse(ostr))";
}
}
out << eb;
out << " catch";
out << sb;
out << nl << "return PromiseKit.Promise(error: error)";
out << eb;
out << eb;
}

bool
Expand Down
1 change: 0 additions & 1 deletion cpp/src/slice2swift/SwiftUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,6 @@ namespace Slice
void writeProxyOperation(::IceUtilInternal::Output&, const OperationPtr&);
void writeProxyAsyncOperation(::IceUtilInternal::Output&, const OperationPtr&);
void writeDispatchOperation(::IceUtilInternal::Output&, const OperationPtr&);
void writeDispatchAsyncOperation(::IceUtilInternal::Output&, const OperationPtr&);

private:
class MetaDataVisitor : public ParserVisitor
Expand Down
Loading

0 comments on commit aaf3836

Please sign in to comment.