Giter VIP home page Giter VIP logo

Comments (5)

eduard-vasinskyi avatar eduard-vasinskyi commented on June 7, 2024 1

Hello, @sirinath
Yes, you can use routing servlet in multithreaded context.
The preffered way is to specify all of the mappings directly.
If you wish, you can omit HTTP method while configuring routes in RoutingServlet. You can determine a method of HTTP request based on result of request.getMethod() call. But it is more convenient to specify the method to be handled. Mappings that do not specify HTTP method are primarly useful for providing fallback servlets, or for combining with other routing servlets that have mappings for multiple methods.

Here is a snippet that demonstrates how to do that:

package io.activej.launchers.http;

import io.activej.http.AsyncServlet;
import io.activej.http.HttpResponse;
import io.activej.http.RoutingServlet;
import io.activej.inject.Injector;
import io.activej.inject.annotation.Named;
import io.activej.inject.annotation.Provides;
import io.activej.worker.annotation.Worker;
import io.activej.worker.annotation.WorkerId;

import static io.activej.http.HttpMethod.GET;
import static io.activej.http.HttpMethod.POST;

public final class ApplicationLauncher extends MultithreadedHttpServerLauncher {

	@Provides
	@Worker
	AsyncServlet servlet(@WorkerId int workerId, @Named("API") AsyncServlet apiServlet) {
		return RoutingServlet.create()
				.map(GET, "/", request -> HttpResponse.ok200()
						.withPlainText("hello world: " + workerId))
				.map("/allMethods", request -> HttpResponse.ok200()
						.withPlainText("Called with HTTP method: " + request.getMethod()))
				.map("/api/*", apiServlet);
	}

	@Provides
	@Worker
	@Named("API")
	AsyncServlet apiServlet(@WorkerId int workerId) {
		return RoutingServlet.create()
				.map(GET, "/resource", request -> HttpResponse.ok200()
						.withPlainText("Getting a resource from worker: " + workerId))
				.map(POST, "/resource", request -> HttpResponse.ok200()
						.withPlainText("Posting a resource to worker: " + workerId));
	}

	public static void main(String[] args) throws Exception {
		Injector.useSpecializer();

		new ApplicationLauncher().launch(args);
	}
}

Note how HTTP method of the request is accessed in /allMethods mapping.
An API servlet that has mappings for different methods is mapped to /api/* endpoint that does not specify HTTP method. As a result, requests are correctly passed to the API servlet to be handled.

To learn more about servlets and how parameters are handled, please refer to examples:
Multithreaded server
Request parameters
Routing servlet

from activej.

eduard-vasinskyi avatar eduard-vasinskyi commented on June 7, 2024 1

Hello, @sirinath
RouterModule is supported only for single-threaded servers. You have to map servlets to corresponding paths by hand, similarly to example from this reply

// Also at this point if I want to read a cookie how do I do it?

You can read a cookie directly from a request by calling either
@Nullable String getCookie(String) - to read a single cookie
or
Map<String,String> getCookies() - to retrieve all of the cookies from a request

You can refer to API of HttpRequest if you need help with accessing cookies or other request parameters. Or you can look at examples on the website that I have provided in previous reply.

Also, what does this piece of code do in the example on your site

Modules.combine() allows you to combine bindings from different modules as if it is a single module. If your application has several modules, you could use Modules.combine() to return a single module from getBusinessLogicModule() method or getOverrideModule().

Also how does getBusinessLogicModule() compare with getOverrideModule()?

If you specify a duplicate binding in getBusinessLogicModule() you will catch an exception, as bindings with same keys are forbidden.
However, if you want to override existing bindings with your own, you can use getOverrideModule() for this. For example, you can override default Config provided in HttpServerLauncher by overriding getOverrideModule() and returning a module that contains binding for a new Config.

You can refer to documentation for more information. Or you can look at API/javadocs of Injector, Launcher or HttpServerLauncher

from activej.

sirinath avatar sirinath commented on June 7, 2024

Simple test code I am using:

import io.activej.http.AsyncServlet;
import io.activej.http.HttpResponse;
import io.activej.http.RoutingServlet;
import io.activej.http.inject.RouterModule;
import io.activej.http.inject.RouterModule.Router;
import io.activej.http.inject.RouterModule.Mapped;
import io.activej.inject.Injector;
import io.activej.launcher.Launcher;
import io.activej.inject.annotation.Provides;
import io.activej.launchers.http.MultithreadedHttpServerLauncher;
import io.activej.worker.annotation.Worker;
import io.activej.inject.module.Module;
import io.activej.inject.module.Modules;
import io.activej.worker.annotation.WorkerId;

public final class ApplicationLauncher extends MultithreadedHttpServerLauncher {
    @Override
    protected Module getBusinessLogicModule() {
        return Modules.combine(new RouterModule());
    }

    @Provides
    AsyncServlet servlet(@Router AsyncServlet router) {
        return router;
    }

    @Provides
    @Worker
    @Mapped("/")
    AsyncServlet main(@WorkerId int workerId) {
        return request -> HttpResponse.ok200().withPlainText("hello world: " + workerId);
    }

    public static void main(String[] args) throws Exception {
        Injector.useSpecializer();

        Launcher launcher = new ApplicationLauncher();
        launcher.launch(args);
    }
}

I get 404 Not Found error.


Also, I want to change the number of threads to java.lang.Runtime.availableProcessors().

from activej.

sirinath avatar sirinath commented on June 7, 2024

@eduard-vasinskyi Any way a multi-threaded and rounding module servlets can be combined, i.e., creating a multi-threaded routing module servelet?

from activej.

sirinath avatar sirinath commented on June 7, 2024

@eduard-vasinskyi

Can I used @Mapped("/xyz") for convenience in the above context? If so how?

E.g. How do I modify your example so that I can have something like:

@Worker
@Provides
@Mapped("/")
AsyncServlet main(@WorkerId int workerId) { 
   return request -> HttpResponse.ok200().withPlainText("hello world: " + workerId) 
}

@Worker
@Provides
@Mapped("/allMethods")
AsyncServlet allMethods(@WorkerId int workerId) { 
   // Also at this point if I want to read a cookie how do I do it?
   return request -> HttpResponse.ok200().withPlainText("Called with HTTP method: " + request.getMethod()) 
}

// Also can I have something like: 
@Worker
@Provides
@Mapped("/allMethodsX")
AsyncServlet allMethodsX(@WorkerId int workerId, @?????? method, @?????? cookie) { 
   return request -> HttpResponse.ok200().withPlainText("Called with HTTP method: " + method + " " + cookie) 
}

@Worker
@Provides
@Named("API")
@Mapped("/api/*")
AsyncServlet api(@WorkerId int workerId) { ... } // I am not sure what goes in here

@Worker
@Provides
@Mapped(value = "/resource", method = RouterModule.MappedHttpMethod.GET)
AsyncServlet getResource(@WorkerId int workerId, @Named("API") AsyncServlet apiServlet) {  
   return request -> HttpResponse.ok200().withPlainText("Getting a resource from worker: " + workerId) 
}

@Worker
@Provides
@Mapped(value = "/resource", method = RouterModule.MappedHttpMethod.POST)
AsyncServlet postResource(@WorkerId int workerId, @Named("API") AsyncServlet apiServlet) { 
   return request -> HttpResponse.ok200().withPlainText("Posting a resource to worker: " + workerId) 
}

Is this possible?


Also, what does this piece of code do in the example on your site:

    @Override
    protected Module getBusinessLogicModule() {
        return Modules.combine(new RouterModule());
    }

Also how does getBusinessLogicModule() compare with getOverrideModule()?

from activej.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.