[JAVA] Je pensais que le dessin initial serait plus rapide si j'utilisais Spring WebFlux pour obtenir 1 million de données du serveur et l'afficher sur le navigateur, alors je l'ai essayé.

L'autre jour, j'ai écrit un article "Obtenir les résultats Flux de Spring Web Flux à partir de JS avec Fetch API", mais en utilisant cette méthode, Par exemple, lorsque vous souhaitez afficher une grande quantité de données sur le navigateur, si le serveur ne peut traiter que les premières dizaines d'éléments, affichez d'abord les premières dizaines d'éléments sur le navigateur, puis ajoutez les données traitées en arrière-plan. Aller. Je pensais qu'il serait possible de faire quelque chose comme ** facilement **, alors je l'ai essayé.

Si l'utilisateur demande une grande quantité de données, il existe une option pour l'implémenter par pagination, Il peut y avoir une telle option. C'est un article sur. Nous ne recommandons pas cette méthode.

Celui que j'ai essayé ici est téléchargé sur GitHub.

Traitement du contenu

Demandez un million de données au serveur et affichez les résultats dans la grille du navigateur.

Éléments techniques utilisés

--Du côté serveur

Comparaison et vidéo

Je vais d'abord vous montrer le résultat de la comparaison.

Requête asynchrone utilisant Spring WebFlux

Le temps du premier dessin était de 2 056 ms. Je pensais que ce serait un peu plus tôt, mais il semble qu'il faut du temps pour que le premier soit renvoyé après l'émission de la requête SQL dans H2 Database. (Eh bien, je ne pense pas que H2 soit destiné à la production, donc il ne peut pas être aidé.) La vidéo a été coupée, mais après cela, il faut environ 40 secondes pour acquérir les données de chorochoro et stocker 1 million du côté client.

WebFlux.gif

Demande de synchronisation ordinaire

Le temps de dessiner était de 5 827 ms. Puisque je les apporte tous en même temps, c'est le même 5 827 ms en termes de temps qu'il faut pour stocker 1 million d'articles côté client. Je pensais que ce serait plus lent, mais je n'ai rien fait dans la construction de chaque disque, et il n'y avait pas beaucoup d'informations sur un disque, donc était-ce étonnamment rapide?

sync.gif

la mise en oeuvre

J'écrirai également sur la mise en œuvre ci-dessous.

Contrôleur (côté serveur)

La mise en œuvre est la suivante.

	@Autowired
	private SqlConfig uroboroSQLConfig;

	@Autowired
	@Qualifier("jdbcScheduler")
	private Scheduler jdbcScheduler;

	@GetMapping
	public Flux<Person> all() {
		return Flux.<Person> create(sink -> {
			try (var agent = uroboroSQLConfig.agent()) {
				//SELECT la table et générer un Stream mappé à la classe Person
				agent.queryWith("SELECT * FROM PERSON ORDER BY ID")
						.stream(Person.class)
						//Quitter si annulé
						.dropWhile(p -> sink.isCancelled())
						//Passer l'entité à FluxSink
						.forEach(sink::next);

				if (!sink.isCancelled()) {
					//Notifier la fin
					sink.complete();
				}
			}
		}).subscribeOn(jdbcScheduler);
	}

La source publiée sur GitHub est [par ici](https://github.com/ota-meshi/spring-webflux-x-cheetah-grid-example/blob/master/src/main/java/example/spring /webflux/controller/PersonController.java#L27).

ʻUroboroSQLConfig` est requis pour l'accès à la base de données de uroboroSQL. Cela n'a rien à voir avec le sujet principal, alors ne vous inquiétez pas, pensez simplement que c'est quelque chose pour l'accès à la base de données et lisez-le en l'air.

Le jdbcScheduler est une instanceScheduler de Reactor qui est requise pour la parallélisation.

Définissez Scheduler avec le nombre approprié de threads,

		}).subscribeOn(jdbcScheduler);

En passant, le traitement de l'accès à la base de données et le traitement du retour d'une requête sont parallélisés.

Le reste est le traitement de l'annulation, Fondamentalement, il suffit de «SELECT» dans la base de données et de transmettre le résultat avec «sink.next (...)».

Demande (côté client)

[Fetch API](https: //developer.mozilla) par la méthode décrite dans Obtenir les résultats Flux de Spring Web Flux à partir de JS avec Fetch API Faites une demande au serveur en utilisant .org / ja / docs / Web / API / Fetch_API).

Affichage sur grille (côté client)

La mise en œuvre est la suivante.

      const records = [];
      const grid = /*Instance Cheetah Grid*/;
      let buffer = [];
      //...
      streamJsonForVue(this, "/api/persons", {}, rec => {
        buffer.push(rec);
        if (
          buffer.length >= 10000 ||
          (records.length < 10000 && buffer.length >= 1000) ||
          (records.length < 1000 && buffer.length >= 100)
        ) {
          records.push(...buffer);
          grid.records = records;
          buffer = [];
          //...
        }
      }).then(() => {
        records.push(...buffer);
        grid.records = records;
        //...
      });

La source publiée sur GitHub est par iciest.

La variable grid contient une instance de Cheetah Grid, et si vous donnez un tableau à la propriété records, les données données seront affichées à l'écran. Ça montre.

La fonction streamJsonForVue a été écrite dans" Obtenir les résultats Flux de Spring Web Flux à partir de JS avec Fetch API ", Fetch API est en cours de traitement. De plus, je fais des choses comme interrompre Fetch lorsque l'écran est supprimé, mais je vais omettre l'explication car cela n'a rien à voir avec le sujet principal.

La variable rec renvoyée par le rappel streamJsonForVue est les données à un enregistrement passées parsink.next (...)dans le contrôleur. Si vous le transmettez à la grille un par un, le redessiner sera exécuté et il sera difficile pour l'utilisateur de faire fonctionner l'écran, alors stockez-le dans le tableau buffer, et quand il s'accumule dans une certaine mesure (100 premiers cas), reflétez-le dans la grille Je le fais.

Implémentation de la demande de synchronisation

La source publiée sur GitHub est [par ici](https://github.com/ota-meshi/spring-webflux-x-cheetah-grid-example/blob/master/src/main/java/example/spring /webflux/controller/PersonController.java#L48) et [par ici](https://github.com/ota-meshi/spring-webflux-x-cheetah-grid-example/blob/master/src/components/SampleCheetahGrid .vue # L131). Je l'ai fait à titre de comparaison uniquement, mais cela n'a rien à voir avec le sujet principal, je vais donc omettre l'explication.

Impressions mises en œuvre

Ce que j'ai pensé de sa mise en œuvre, c'est que c'était ** très facile à mettre en œuvre **. À ma connaissance, il était difficile d'envoyer une réponse HTTP à Stream de manière asynchrone, mais j'ai été surpris car c'était très facile à faire avec Spring WebFlux.

résultat

Comme je l'ai écrit plus tôt, dans cet exemple, le temps requis pour le dessin initial était le suivant.

Il est dommage que cet échantillon ne soit pas aussi efficace que prévu, mais il peut être utile si vous voulez vraiment accélérer le dessin initial (?).

Recommended Posts

Je pensais que le dessin initial serait plus rapide si j'utilisais Spring WebFlux pour obtenir 1 million de données du serveur et l'afficher sur le navigateur, alors je l'ai essayé.
J'ai essayé de vérifier si ce serait amusant de combiner «programmation» et «hobbies».
J'ai essayé d'appeler une vidéo YouTube de DB avec haml et de l'afficher intégrée
J'ai essayé de démarrer avec Spring Data JPA