Beispiel #1
0
Server::OldAPI::CallResult Server::OldAPI::callMethod(BredyHttpSrv::IHttpRequestInfo* httpRequest,
				ConstStrA methodName, const JSON::Value& args,
					const JSON::Value& context, const JSON::Value& id) {


	class FakePeer: public IPeer {
	public:
		virtual BredyHttpSrv::IHttpRequestInfo *getHttpRequest() const {return req;}
		virtual ConstStrA getName() const {
			return req->getIfc<BredyHttpSrv::IHttpPeerInfo>().getPeerRealAddr();
		}
		virtual natural getPortIndex() const {
			return req->getIfc<BredyHttpSrv::IHttpPeerInfo>().getSourceId();
		}
		virtual IRpcNotify *getNotifySvc() const {
			return 0;
		}
		virtual void setContext(Context *ctx) {
			this->ctx = ctx;
		}
		virtual Context *getContext() const {
			return ctx;
		}
		virtual IClient *getClient() const {
			return 0;
		}
		virtual natural getVersion() const {
			return version;
		}

		ContextVar ctx;
		BredyHttpSrv::IHttpRequestInfo *req;
		natural version;

		FakePeer(BredyHttpSrv::IHttpRequestInfo *req,natural version):req(req),version(version) {}
	};


	FakePeer fakePeer(httpRequest, this->version);
	WeakRefTarget<IPeer> peer(&fakePeer);
	JSON::Builder json;
	Request req;
	req.context = context;
	req.params = args;
	req.id = id;
	req.methodName = json(methodName);
	req.isNotification = false;
	req.dispatcher = owner.getDispatcherWeakRef();
	req.peer = peer;
	req.json = json.factory;

	CallResult cres;
	Future<Response> resp = owner.callMethod(req);
	cres.id = id;
	try {
		const Response &result = resp.getValue();
		cres.error = JSON::getConstant(JSON::constNull);
		cres.result = static_cast<const JSON::Value &>(result.result);
		cres.newContext = static_cast<const JSON::Value &>(result.context);
		cres.logOutput = result.logOutput;
		return cres;
	} catch (jsonsrv::RpcError &e) {
		cres.error = e.getError();
		cres.result = JSON::getConstant(JSON::constNull);
		cres.logOutput = cres.error;
		return cres;
	} catch (RpcException &e) {
		cres.error = const_cast<JSON::INode *>(e.getJSON(json).get());
		cres.result = JSON::getConstant(JSON::constNull);
		cres.logOutput = cres.error;
		return cres;
	}
}
// The primary thread function, which issues calls through the secondary thread
void rundemos()
{
	// Create an event for which our second thread will wait
	hExternalEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

	// Create the secondary thread
	DWORD dwThreadId;
	HANDLE hThread = CreateThread(NULL, 0, demoThread, NULL, 0, &dwThreadId);

	// Obtain a scheduler instance, through which we can make cross thread calls
	CallScheduler<APCPickupPolicy>* scheduler = CallScheduler<APCPickupPolicy>::getInstance();

	// Do a first cross thread call, to a function returning a string
	try
	{
		string dataString = scheduler->syncCall<string, ExceptionTypes<std::exception>>(dwThreadId, boost::bind(demoFunction, 'a'), INFINITE);
		cout << "demoFunction returned: " << dataString << endl;
	}
	catch(CallTimeoutException&)
	{
		cout << "Call timeout." << endl;
	}
	catch(CallSchedulingFailedException&)
	{
		cout << "Call scheduling failed -- Probably a broken pickup policy." << endl;
	}
	catch(std::exception& e)
	{
		cout << "The scheduled call threw a std exception: " << e.what() << endl;
	}

	// Do a second cross thread call, to a function returning nothing
	try
	{
		// Expect a std::exception or DemoException
		scheduler->syncCall<void, ExceptionTypes<std::exception, DemoException>>(dwThreadId, boost::bind(demoVoidFunction, 'a'), 500);
	}
	catch(CallTimeoutException&)
	{
		cout << "Call timeout" << endl;
	}
	catch(CallSchedulingFailedException&)
	{
		cout << "Call scheduling failed -- Probably a broken pickup policy." << endl;
	}
	catch(std::exception& e)
	{
		cout << "demoVoidFunction threw a std exception: " << e.what() << endl;
	}
	catch(DemoException&)
	{
		cout << "demoVoidFunction threw a DemoException" << endl;
	}

    // Do a third cross thread call, to a function returning an int
    try
    {
        // Expect a std::exception or DemoException
        int demoInt = scheduler->syncCall<int, ExceptionTypes<std::exception, DemoException>>(dwThreadId, boost::bind(demoIntFunction, '!'), 500);
        cout << "demoIntFunction returned: " << demoInt << endl;
    }
    catch(CallTimeoutException&)
    {
        cout << "Call timeout" << endl;
    }
    catch(CallSchedulingFailedException&)
    {
        cout << "Call scheduling failed -- Probably a broken pickup policy." << endl;
    }
    catch(std::exception& e)
    {
        cout << "demoIntFunction threw a std exception: " << e.what() << endl;
    }
    catch(DemoException&)
    {
        cout << "demoIntFunction threw a DemoException" << endl;
    }

    // Do a fourth cross thread call, to a function returning an int
    try
    {
        boost::function<int()> f = boost::bind(demoIntFunctionDelayed, '!');
        Future<int> futureDemoInt = scheduler->asyncCall<ExceptionTypes<DemoException, std::exception>>(dwThreadId, f);
        
        //Future<int> futureDemoInt2 = scheduler->asyncCall<ExceptionTypes<DemoException, std::exception>>(dwThreadId, boost::bind(demoIntFunctionDelayed, '!'));
        Future<void> futureDemoInt3 = scheduler->asyncCall<void>(dwThreadId, boost::bind(demoIntFunctionDelayed, '?'));
        Future<int> futureDemoInt4 = scheduler->asyncCall<int>(dwThreadId, boost::bind(demoIntFunctionDelayed, '!'));
        Future<int> futureDemoInt5 = scheduler->asyncCall<int, ExceptionTypes<DemoException>>(dwThreadId, boost::bind(demoIntFunctionDelayed, '!'));
        Future<void> futureDemoInt6 = scheduler->asyncCall<void, ExceptionTypes<DemoException>>(dwThreadId, boost::bind(demoIntFunctionDelayed, '!'));
        Future<void> futureDemoInt7 = scheduler->asyncCall<ExceptionTypes<DemoException>, void>(dwThreadId, boost::bind(demoIntFunctionDelayed, '!'));
        Future<int> futureDemoInt8 = scheduler->asyncCall<ExceptionTypes<DemoException>, int>(dwThreadId, boost::bind(demoIntFunctionDelayed, '!'));

        while(futureDemoInt.wait(10) == ASYNCH_CALL_PENDING)
        {
            cout << "Still waiting ..." << endl;
        }
        cout << "demoIntFunctionDelayed returned: " << futureDemoInt.getValue() << endl;
    }
    catch(CallSchedulingFailedException&)
    {
        cout << "Call scheduling failed -- Probably a broken pickup policy." << endl;
    }

	// Cleanup
	SetEvent(hExternalEvent);
	WaitForSingleObject(hThread, INFINITE);
	CloseHandle(hThread);
	CloseHandle(hExternalEvent);
}