netcal / dnc Goto Github PK
View Code? Open in Web Editor NEWThe NetworkCalculus.org Deterministic Network Calculator
Home Page: http://dnc.networkcalculus.org
License: GNU Lesser General Public License v2.1
The NetworkCalculus.org Deterministic Network Calculator
Home Page: http://dnc.networkcalculus.org
License: GNU Lesser General Public License v2.1
Calculator is a singleton at the moment, all methods can be used via getInstance. If we can agree that it will be always a singleton, we could change all methods and variables to static. Do a pheasability check first, also check whether in later releases we could you two different calculators paralelly ( in that case it cannot be a singleton anymore).
We assemble the test configurations in DncTestMethodSources.java. Alternative Curve and Number Backends are hardcoded, even if they are non-essential extension (e.g., MPA RTC Curve Backend). I.e., we have a compile time dependency.
Can somehow make the tests look for "plugins" during runtime to break this compile-time dependency. I am thinking of a way that the plugin tells the test what it provides (e.g., a Num / Curve / Operator interface implementation) and the tests dispatch to it accordingly.
Using OSGi seems too much overhead to achieve this.
Some speculation: Can we put jar files into a plugin directory. Their names or a bundled descriptor file could probably follow a specific pattern that indicates capabilities (i.e., implemented interfaces). For example, the name pattern could be {short interface path/name}-{plugin name}.jar and RTC MPA code would then be in curve_CurvePwAffine-MPA_RTC.jar. We only hardcode the package prefix "de.uni_kl.cs.discodnc." in our code, the remainder would be found in the jar name. The example refers to the sub-package "curve" and implements interface CurvePwAffine (indicated by the capital letter). The name of our implementation is MPA_RTC and all the code needs to be in the de.uni_kl.cs.discodnc.curve package (this last point is subject to more refinement, in particular if we use a descriptor file instead).
Hi everybody,
I am a freshman and I am applying DNC to my project. I would say I have a question, not an issue.
Does TFA take into account the interference of data streams? I have different streams going through certain servers. When looking at the delay bound of foi, I would be interested to know if the interference of other streams passing through the same server has been taken into account.
Thank you
I have a tool that performs RTC analysis which i want to contribute as an open source tool. It uses the jar provided by the RTC-MPA toolbox as a backend for curve representation and manipulation. I could find any information regarding the licensing status of that binary which i noticed that it's being used also by this project.
My question is as follows: under which license does the DNC project use that jar file.
I know that this is a question to be asked to the developers of the jar but i couldn't find any information that way. Any information from contributors to this project would be appreciated.
Thanks.
Hello,
After performing all the steps described, the project compilation gives the following error: "Missing artifact org.networkcalculus.model:NetCal-NetworkModel:jar:0.0.1-SNAPSHOT." When the project will compile it needs Num and NetworkModel (line 70 pom.xml file), but in maven repositories only Num appears, there is no NetworkModel. So I tried to install NetworkModel via https://github.com/NetCal/NetworkModel but it also gives a compilation error, the error is: "ERROR Mwe2Launcher - Problems running workflow GeneratemodelCode: java.io.IOException: The path '/NetCal-NetworkModel/model/network.genmodel' is unmapped."
Anyone with any idea to make the compilation without errors?
While investigating issue #11, I thought about current and future code sharing between curve.dnc_affine and curve.dnc_pwaffine. Methods in the respective curve classes will definitely diverge, yet, I do not think that the rather simplistic LinearSegment class ever will. Thus, I suggest sharing it between both implementations. To do so, an adaptation our package hierarchy probably best:
such that the LinearSegment class we maintain can be moved into package curve.dnc
Goal: Reduce code duplication of extensions that come with adapted test arguments.
Challenge: The test results need to know the flows in the test network in order to map the correct results to them. Moreover these results might also change, depending on the analysis config (i.e., not only the analysis itself).
Thus, a test class must instantiate its network and the results classes correctly before executing the actual tests it defines.
Hi,
The DiscoDNC project faces 840 test failures out of 2720 tests, leading to a build failure.
[INFO] [ERROR] Tests run: 2720, Failures: 840, Errors: 0, Skipped: 0 [INFO] [INFO] ------------------------------------------------------------------------ [INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ [INFO] Total time: 01:26 min [INFO] Finished at: 2023-08-01T10:50:04+02:00 [INFO] ------------------------------------------------------------------------ [ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.22.2:test (default-test) on project NetCal-DNC: There are test failures.
For illustration, the NumBackend is a good example. There, we provide Num create{Zero,PositiveInfinity,NegativeInfinity} as well as Num get{Zero,PositiveInfinity,NegativeInfinity}. Moreover, there we have the boolean is{Zero,PositiveInfinity,NegativeInfinity}.
Those implemented hashCode() methods in some classes generate the same output (hash collision) when swapping multiplying operands.
An incorrect implementation of hashCode() and equals() methods may cause errors that are hard to debug when a class is used as a Map key.
I have searched by this usage and I found the following classes with that mistake:
For example, in Turn class we have:
public int hashCode() {
return (int) src.hashCode() * dest.hashCode();
}
This hashCode implementation will generate same output value when swapping src to dest.
The following classes are using a Turn object as a Map key.
A simple way to fix this is by using Objects.hash(...) method with the class attributes:
public int hashCode() {
return Objects.hash(src, dest);
}
Also, other classes are using the hashCode() method with multiplying.
It is recommended to fix them using Objects.hash(...) method instead of multiplying attribute values.
At running the Total Flow Analysis of an Ethernet network example in org.networkcalculus.dnc.standards.ethernet.demos.Ethernet_Demo2.java
of my DNC fork it throws a StackOverflowError exception.
Note: This example is like a converter. It produces instances of DNC classes to run the analysis.
Note2: All the servers are using ServiceCurve
and MaxServiceCurve
with rate-latency functions, and these curves are created with the same rate
and latency
input values. Can I do this?
Do you have any suggestion on how to fix this?
The following text is written in console:
Flow of interest : Flow(f2, 2, AC{(0.0,0.0),0.0;!(0.0,1500.0),1000000.0}, {Turn(s_out_CAM1.eth0->s_in_S1.eth2, 43, Server(s_out_CAM1.eth0, 11), Server(s_in_S1.eth2, 27)),Turn(s_in_S1.eth2->s_swfab_S1, 6, Server(s_in_S1.eth2, 27), Server(s_swfab_S1, 22)),Turn(s_swfab_S1->s_out_S1.eth3, 3, Server(s_swfab_S1, 22), Server(s_out_S1.eth3, 30)),Turn(s_out_S1.eth3->s_in_S_center.eth0, 57, Server(s_out_S1.eth3, 30), Server(s_in_S_center.eth0, 53)),Turn(s_in_S_center.eth0->s_swfab_S_center, 26, Server(s_in_S_center.eth0, 53), Server(s_swfab_S_center, 52)),Turn(s_swfab_S_center->s_out_S_center.eth5, 31, Server(s_swfab_S_center, 52), Server(s_out_S_center.eth5, 64)),Turn(s_out_S_center.eth5->s_in_ECU_Cam.eth0, 66, Server(s_out_S_center.eth5, 64), Server(s_in_ECU_Cam.eth0, 8))})
--- Total Flow Analysis ---
Exception in thread "main" java.lang.StackOverflowError
at java.base/java.util.AbstractList$SubList.listIterator(AbstractList.java:838)
at java.base/java.util.AbstractList.listIterator(AbstractList.java:311)
at java.base/java.util.AbstractList$SubList.iterator(AbstractList.java:831)
at java.base/java.util.AbstractCollection.toArray(AbstractCollection.java:140)
at java.base/java.util.LinkedList.addAll(LinkedList.java:412)
at java.base/java.util.LinkedList.addAll(LinkedList.java:391)
at java.base/java.util.LinkedList.<init>(LinkedList.java:123)
at org.networkcalculus.dnc.network.server_graph.Path.getSubPath(Path.java:136)
at org.networkcalculus.dnc.network.server_graph.Flow.getSubPath(Flow.java:198)
at org.networkcalculus.dnc.feedforward.arrivalbounds.AggregatePboo_Concatenation.computeArrivalBound(AggregatePboo_Concatenation.java:98)
at org.networkcalculus.dnc.feedforward.ArrivalBoundDispatch.computeArrivalBounds(ArrivalBoundDispatch.java:176)
at org.networkcalculus.dnc.feedforward.ArrivalBoundDispatch.computeArrivalBounds(ArrivalBoundDispatch.java:127)
at org.networkcalculus.dnc.feedforward.arrivalbounds.AggregatePboo_Concatenation.computeArrivalBound(AggregatePboo_Concatenation.java:127)
at org.networkcalculus.dnc.feedforward.ArrivalBoundDispatch.computeArrivalBounds(ArrivalBoundDispatch.java:176)
at org.networkcalculus.dnc.feedforward.ArrivalBoundDispatch.computeArrivalBounds(ArrivalBoundDispatch.java:127)
at org.networkcalculus.dnc.feedforward.arrivalbounds.AggregatePboo_Concatenation.computeArrivalBound(AggregatePboo_Concatenation.java:127)
at org.networkcalculus.dnc.feedforward.ArrivalBoundDispatch.computeArrivalBounds(ArrivalBoundDispatch.java:176)
at org.networkcalculus.dnc.feedforward.ArrivalBoundDispatch.computeArrivalBounds(ArrivalBoundDispatch.java:127)
at org.networkcalculus.dnc.feedforward.arrivalbounds.AggregatePboo_Concatenation.computeArrivalBound(AggregatePboo_Concatenation.java:127)
at org.networkcalculus.dnc.feedforward.ArrivalBoundDispatch.computeArrivalBounds(ArrivalBoundDispatch.java:176)
at org.networkcalculus.dnc.feedforward.ArrivalBoundDispatch.computeArrivalBounds(ArrivalBoundDispatch.java:127)
at org.networkcalculus.dnc.feedforward.arrivalbounds.AggregatePboo_Concatenation.computeArrivalBound(AggregatePboo_Concatenation.java:127)
Running the attached demo code (put into demo package of DiscoDNC v2.4.2), SFA throws a class cast exception.
The expected behavior is to throw an exception saying "No service left over" or to compute a left-over service curve for the flow of interest that is zero. The latter is done by PMOO, i.e., unifying the behavior by removing this exception would make sense, too.
It seems that we can define a function with at most two segments. In this case, if we use a token bucket model to simulate a flow with periodic burst (in which a lot of detailed are lost), the calculted e2e delay is to pessmistic. How to deal with this issue?
Looking forward to your reply. Thank you!
Tao Gao
Tests should not be copied through dependent projects but should be available as a dependency.
At the moment dependencies also contain jars that are transitive from other projects so they can be skipped. Scope of the dependencies should also be set properly (all junit is only needed for scope=test).
Without this change maven will not compile new source directories.
pom.xml needs a bit more refactoring:
I have some code using the DNC library where I perform analyses of multiple networks in different threads. This leads to errors in the analyses which do not appear when only one thread is used.
Some debugging lead me to ArrivalBoundDispatch.java
and the arrivalbound classes. Singletons are used for doing the computations, and use setServerGraph(server_graph)
and setConfiguration(configuration)
to configure it, before calling computeArrivalBound
. The issue is that if there are multiple threads, you might have the case that setServerGraph
is executed by one thread, while another thread is still executing computeArrivalBound
. I validated my theory by creating a new arrivalbound instance for each computation, resulting in no errors. ArrivalBoundCache
, in its current implementation, is also not thread-safe.
Hence, I suggest to modify DNC library in order to use thread-safe data structures, and thus enable parallelization of (some) computations.
In branch v2.5 after merging #2 and adding AffineCurves to Junit tests I recognized that some of the tests fail as they have different results. Should results depend on the Curve type?
May I ask if the DNC tool supports cyclic dependency networks and the corresponding fixed point function? Or it only support non-cycle dependency networks (such as Tandem, Tree and Feed-forward)?
Looking forward to your reply. Thank you!
spzhan
Method public Num getXIntersection(Curve curve1, Curve curve2){...}
from class CurveUtils_Disco_PwAffine
has a possible typo mistake on its implementation.
curve1
should use index i
and curve2
should use index j
However, related indexes are inverted in following lines:
I am preparing a pull request with these fixes.
In SinkTree_AffineCurves, there are two separate methods for affine and piecewise affine curve computations based on the given min-plus operations:
computeArrivalBoundDeConvolution
and computeArrivalBoundDeConvolutionTBRL
where the latter used to set the flag to use token-bucket/rate-latency convolution and deconvolution. Now that the two paths have been separated in a new way, that is by setting the backend configuration accordingly, both methods compute the same (which, depending on this configuration might not be what their respective name indicates). We thus need a different solution to make this code work as supposed, again.
Hello everyone,
As per the question placed here #106, the NCorg DNC does not support stair-/step-functions at the moment. What if I apply the packetizing effect on R' (t) (L-packetized output) and receive continuous function instead of discrete? Hence the packetizing will weaken the service curve guarantee by one maximum packet length l max/R .
If it is helpful, my question is how we define l max for the minimum service curve of B' if two input arrival curves have their l max_1 and l max_2?
arrival_curve_1 = l max_1 + rt
arrival_curve_2 = l max_2 + rt
B'= B - l max
So l max of minimum service curve of the combined system (bit-by-bit system with L-packetizer) will be the sum of l max_1 and l max_2 or supremum of arrival curves l max?
Many thanks for your reply.
Kind regards,
Nurbek
As we are currently adding code that is specialized to certain curve shapes (Affine and PwAffine), we seem to have silently decided that is is not enough to place the according interface implementations (classes) in a separate and reasonably named package. We also vary the class name by a prefix and/or suffixes to include all the specializations. Imho, this is not a problem. Yet, we do so in an inconsistent way. I would like to agree on a common naming convention to be implemented before the first release of specialized code.
Here are my observations (probably also introduced by me):
I recommend to:
Hey everyone,
I am going to apply data flows based on a packet system rather than a bit-by-bit system in my implementation to receive a better worst-case analysis. As far as I understood from the script page 41, section 7.3, we have to consider L-packetized curves. My question refers to the definition of packetized service curve and whether we can implement it in DISCO DNC toolbox. How to set up Lmax in DNC?
Could you please help me with this issue?
Kind regards,
Nurbek
Networks are composed of servers and flows that are, in turn, partially defined by curves. These curves naturally hold numbers (Num instances) of a certain representation defined in the Calculator. In case the representation is changed (e.g., in tests), the current solution is to create a new Network instance. Instead, a Network instance should be able to just trigger updates of its member variables.
As of version 2.5.2, we have the following in the pom.xml
's mpa profile to download the rtc.jar
:
<plugin>
<groupId>com.googlecode.maven-download-plugin</groupId>
<artifactId>download-maven-plugin</artifactId>
<version>${maven.download.plugin.version}</version>
<executions>
<execution>
<id>get-mpa-rtc</id>
<phase>validate</phase>
<goals>
<goal>wget</goal>
</goals>
<configuration>
<url>http://www.mpa.ethz.ch/static/download.php?file=RTCToolbox_bin.zip</url>
<unpack>true</unpack>
<outputDirectory>${project.basedir}/lib/</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
For some file systems, in particular Windows ones (FAT and NTFS), the question mark ?
is a reserved character. Unfortunately, the above code tries to save the zip file under the name download.php?file=RTCToolbox_bin.zip
before unzipping and deleting it. This first step fails on some file systems like NTFS. For example, Maven will fail on Windows saying:
Caused by: java.io.FileNotFoundException: C:\Users\user_s_path\DNC\lib\download.php?file=RTCToolbox_bin.zip (The filename, directory name, or volume label syntax is incorrect)
at java.base/java.io.FileOutputStream.open0(Native Method)
at java.base/java.io.FileOutputStream.open(FileOutputStream.java:292)
at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:235)
at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:185)....
http://www.mpa.ethz.ch/static/download.php?file=RTCToolbox_bin.zip
and unzip it into the /lib
directory.pom.xml
, remove the above plugin from the mpa profile.Thanks to Sidharth Sharma for reporting by email.
@sbondorf and I discussed a potential rework of the current code and repository structure. Imho the current state of having 4 repositories that are needed to compile the DiscoDNC, without references to each other, is not very intuitive. Moreover specific compile instructions are missing. Thus I would like to restructure the repositories and rebuild the original and more intuitive package structure. @matyesz, I would like to discuss the following idea.
Basic Idea:
Rebuild the original hierarchy, with the core DNC code contained in this repository in src/main/java
, the tests in src/test/java
and the MPA extension in src/mpa_ext/java
, while the code of the latter ones is still kept in their respective repositories.
In order to achieve this, git submodules are used to create a reference to the respective repository in src/mpa_ext
and src/test
. The two repositories will only contain the packages that contain the code an fit in the proposed hierarchy. When checking out the core repository the respective submodules can be added as needed, since they are not automatically included.
The only pom.xml
will be found in this repository, including two profiles. One for adding the mpa extension to a compiled jar and one for creating an additional jar for the tests. Since there is no point in compiling those two parts without the core code, there is no need for additional poms.
The meta repository will become obsolete.
The resulting file structure looks like this:
DiscoDNC repository
| - pom.xml
| - src
| - main/java/... (core code)
| - mpa_ext (submodule/reference to the mpa_ext repository)
| - java/... (mpa wrapper code contained in the DiscoDNCext_MPARTC repository)
| - test (submodule/reference to the DiscoDNC_tests repository)
| - java/... (test classes)
| - ... other files in this repository
The benefits of this structure:
For testing purposes I created private repositories that represent the above structure using a small set of classes and packages. I can provide access if you want to have a look at it.
Existing solution with forcing toString() and having assembleString on the interface is not optimal. Could be do with just implementing toString(). Investigate and refactor.
There are different representations (that is, set of linear segments) for specific curve shapes, in particular the ones we offer convenient create* methods for -- see details and example below.
The create* methods create the according function in one specific way of representing it. Exactly this way is required to trigger the shortcuts in the code, e.g., to identify the "zero delay, infinite burst" curve as the neutral element of convolution. Calling the beautify() method does not map alternative representations to the one chosen for the create* methods (needs further investigation, but I am fairly certain). Unfortunately, neither these shortcuts nor using the generic code path for special curves is covered by our tests. Thus, I am not certain if this issue is a bug report or a feature request ... (there had been a related bug, reported by GSI, and fixed in v2.2.8).
Details and example: Take the implementation of "delayed infinite burst" curve with delay d in Curve_DNC.java. The is makeDelayedInfiniteBurst method creates these two segments:
Checking for this shape invokes Curve_DNC's equals method that iterates over these segments, calls LinearSegment's equals that, in turn, only checks if the above values match one by one as it does not know the context of belonging to a "delayed infinite burst" curve. However, in this context some values do not matter: the rate (>=0) of the second segment is irrelevant as its y-coordinate is already +infty (ok, this actually holds independent of the context).
Also, in other context, there are other irrelevant values. Take the "zero delay, infinite burst" curve where the rate of the first segment does not matter as it is actually only the point in the origin.
The same overall situation might apply to zero{Arrivals,Service} and potentially others.
Currently, the generic Interfaces for ArrivalCurve, ServiceCurve and MaxServiceCurve extend CurvePwAffine. I.e., they are in the third level of the hierarchy (see attached image taken from the ECRTS Paper of @phschon and @sbondorf). Thus they carry information about semantics and shape. They should move one level up. Then, for example, a piece-wise affine arrival curve has to implement the interfaces ArrivalCurve and PwAffineCurve.
Oracle is changing their Java license terms with Java 11. I tried reading up, but I still don't know if we are affected by this change or not. Therefore, I suggest to stay on Java 10 as long as possible and to explore the possibility to switch to OpenJDK.
What raises my concerns is that, if I understood correctly, using their JVM is not necessarily free anymore. Yet, I am not certain if / how the terms "commercial" and "in production" apply to us.
This is due to the academic workflow: We make use of the JVM to create evaluation results, write a scientific paper about them, and hope for acceptance at a conference or in a journal. Upon acceptance, we usually have to sign over the copyright to the publisher (IEEE, ACM, Springer, etc.) and they commercialize our work as downloads from their repositories are not free of charge.
In the future (Java 11+), do I have to use OpenJDK for research? I don't know ... At the moment, it seems safer to me to make the switch to OpenJDK.
Although it is set to use both CurveImpl types, tests only use the default (DNC) value.
Hi @sbondorf and @alexscheffler
I am trying to use SFA and FIFO multiplexing but I am not able because I am facing some unexpected Exceptions during analyzes.
I have set config.enforceMultiplexing(MultiplexingEnforcement.GLOBAL_FIFO);
before run analyzes.
In my network setup there are some servers in tandem. So at using SFA and FIFO multiplexing, then convolutions of service curves shall occur.
I have debug DNC's code and found there is an issue in Convolution_Disco_PwAffine.convolveFIFO
method when convolving a rate-latency service curve with a zero-rate-zero-latency service curve. Which it does not occur when using ARB mux, i.e., Convolution_Disco_PwAffine.convolveARB
method.
The following example code may help to reproduce the problem:
ServiceCurve service_curve_0 = Curve.getFactory().createServiceCurve("SC{(0.0,0.0),0.0;!(233.2,0.0),67.19999999999999}");
ServiceCurve service_curve_1 = Curve.getFactory().createServiceCurve("SC{(0.0,0.0),0.0}");
ServiceCurve result_convolveARB = Convolution_Disco_PwAffine.convolveARB(service_curve_0, service_curve_1);
System.out.println("result_convolveARB: " + result_convolveARB);
ServiceCurve result_convolveFIFO = Convolution_Disco_PwAffine.convolveFIFO(service_curve_0, service_curve_1);
System.out.println("result_convolveFIFO: " + result_convolveFIFO);
Output for this code is:
result_convolveARB: SC{(0.0,0.0),0.0}
result_convolveFIFO: SC{(0.0,NaN),0.0}
Can you please take a look at that issue?
Constants (like infinite service curve or 0 arrival curve) should be moved to a separate constant pool. At the moment each call initializes variables that makes the code ineffective during runtime.
Note that constants dependenc on the calculator instance!
I.e., other than writing Java classes to the file system.
Discussion started in Issue #8, with @matyesz raising the following point
"An idea (please evaluate):
we could use xsd to create the network model and generate java code with jaxb.
Pros:
xsd has visual editors so you edit the network model as an uml, easy to change
xml support out of the box - network can be described both in java or via xml (users have their data in db so it is easier for them to have an xml extra"
Eclipse does not support Java 11 at the moment although netcal compiles with it. Add descption in README.md.
The current DiscoDNC network backend (as of version 2.4) does not fully implement the entire network modeling stack of network calculus, see [1]. It is limited to the specific network representation required for an analysis.
Details:
Currently the network backend is limited by the Network.java class. It offers a generic implementation storing a directed graph whose vertices represent servers and edges represent links -- classes exist for both these parts of a network. The server requires a service curve to be instantiated and thus it is intended to store a server graph only.
Additionally, while flows must be routed in the server graph, finding reasonable paths is not possible without information about the device graph. Note that a device like a router can add multiple servers to the server graph, e.g., one for each of its output queues. Without a mapping to from devices to servers, the source and destination server (in case of output queueing even a server of the devices before the destination device) are simply not known.
Besides routing, this lack of information inhibits a proper integration of turn prohibition that relies on the mapping of devices to servers in order to feed-forwardize the server graph (again, see [1] and the references therein).
Currently, a network instance can be used out of its indented context and take the role of a device graph. Yet, the Network class should rather take a superordinate role, i.e., be extended to store multiple representations (device graph, server graph, feed-forwardized server graph) and provide turn prohibition as well as routing between devices in the feed-forwardized server graph.
[1] Iterative Design Space Exploration for Networks Requiring Performance Guarantees (Bruno Cattelan, Steffen Bondorf), In IEEE/AIAA 36th Digital Avionics Systems Conference (DASC 2017), 2017.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.