Comments (17)
I've never seen this particular error. Can you provide a test case where we can reproduce it?
from chaco.
Great you are responding so quickly!
Please apologize the delay. Below please find pasted code with which I can produce the error. Normally I run it in ipython -wthread using the run magic command.
After a while different tracebacks should pop up and eventually crash the interpreter.
You can stop the thread by
b.stop()
When you uncomment the lines
b.plot.value_range.low_setting = 0.0
b.plot.value_range.high_setting = 1e6
the bug is gone.
Many thanks and many greetings,
Helmut
issue_9.py:
import threading
import numpy
from enthought.traits.api import SingletonHasTraits, Array, Instance
from enthought.traits.ui.api import View, Item
from enthought.enable.api import Component, ComponentEditor
from enthought.chaco.api import ArrayPlotData, Plot
class Bug( SingletonHasTraits ):
"""Produces a bug in chaco."""
data = Array( value=numpy.zeros(100) )
def _data_changed(self):
self.plot_data.set_data('y', self.data)
plot_data = Instance( ArrayPlotData )
def _plot_data_default(self):
return ArrayPlotData(x=numpy.arange(100), y=self.data)
plot = Instance( Plot )
def _plot_default(self):
plot = Plot(self.plot_data, resizable='hv')
plot.plot(('x','y'), style='line', color='blue')
return plot
def start(self):
self.stop_request = threading.Event()
threading.Thread(target=self.run).start()
def stop(self):
self.stop_request.set()
def run(self):
while True:
self.stop_request.wait(0.001)
if self.stop_request.isSet():
break
self.data = self.data + numpy.random.random_integers(10, 100, 100)
traits_view = View(Item('plot', editor=ComponentEditor(), show_label=False, resizable=True),)
if name == 'main':
b = Bug()
b.edit_traits()
"""
b.plot.value_range.low_setting = 0.0
b.plot.value_range.high_setting = 1e6
"""
b.start()
from chaco.
Can you try to run it from plain-old python? I occasionally get the feeling
the ipython interweaving of the wx event loop causes weirdness with event
ordering.
Bryce
On Tue, May 24, 2011 at 1:27 PM, HelmutFedder <
[email protected]>wrote:
Great you are responding so quickly!
Please apologize the delay. Below please find pasted code with which I can
produce the error. Normally I run it in ipython -wthread using the run magic
command.After a while different tracebacks should pop up and eventually crash the
interpreter.You can stop the thread by
b.stop()
When you uncomment the lines
b.plot.value_range.low_setting = 0.0
b.plot.value_range.high_setting = 1e6the bug is gone.
Many thanks and many greetings,
Helmut
issue_9.py:
import threading
import numpyfrom enthought.traits.api import SingletonHasTraits, Array, Instance
from enthought.traits.ui.api import View, Item
from enthought.enable.api import Component, ComponentEditor
from enthought.chaco.api import ArrayPlotData, Plotclass Bug( SingletonHasTraits ):
"""Produces a bug in chaco."""
data = Array( value=numpy.zeros(100) )
def _data_changed(self):
self.plot_data.set_data('y', self.data)plot_data = Instance( ArrayPlotData )
def _plot_data_default(self):
return ArrayPlotData(x=numpy.arange(100), y=self.data)plot = Instance( Plot )
def _plot_default(self):
plot = Plot(self.plot_data, resizable='hv')
plot.plot(('x','y'), style='line', color='blue')
return plotdef start(self):
self.stop_request = threading.Event()
threading.Thread(target=self.run).start()def stop(self):
self.stop_request.set()def run(self):
while True:
self.stop_request.wait(0.001)
if self.stop_request.isSet():
break
self.data = self.data + numpy.random.random_integers(10, 100,
100)traits_view = View(Item('plot', editor=ComponentEditor(),
show_label=False, resizable=True),)if name == 'main':
b = Bug()
b.edit_traits()
"""
b.plot.value_range.low_setting = 0.0
b.plot.value_range.high_setting = 1e6
"""
b.start()Reply to this email directly or view it on GitHub:
#9 (comment)
from chaco.
Dear Bryce,
did you have time to look into this?
That would be of big help!
Many greetings,
Helmut
from chaco.
Dear Bryce,
since I haven't heard back from you, I want to raise my voice again and stress the importance of this issue.
We are a team of physicists who is currently developing a set of python modules for experiment control in quantum computing applications (Rabi, Ramsey, Coherent control, etc.). The modules contain python backends for a large number of equipment, amongst, fast time sequence generators, single photon time tagging, NI based analog and digital IO, microwave synthesizers, etc.. The measurements include confocal microscopy, Electron spin resonance Nuclear spin resonance, and coherent control of single and multiple Quantum bits.
http://code.google.com/p/pi3diamond/
As it stands now the damaged regions issue is the major show stopper (it frequently kills our measurements, sometimes with fatal loss of expensive samples).
Therefore we would greatly appreciate if someone can take care about this issue.
The project is spearheaded by the university of Stuttgart. By now more than five other university groups have joined the project amongst, Harvard, Berlin and Vienna.
I should mention. Altogether there are about 60 scientists working with our code. Moreover, as you know, the the turnover of students and postdocs is large. Thus, indeed we bring a large number of young people in touch with your packages.
Your support would be very much appreciated.
Sincerely,
Dr. Helmut Fedder
from chaco.
hi Helmut,
It seems the error is tightly linked to the refresh speed. Do you really need 1ms ? With a refresh rate of 25Hz, you do not get the error. You could keep the refresh rate for the data but trigger a graph update only at a human eye rate if needed.
from chaco.
Dear Didrik,
indeed, in our real application this issue occurs even with much lower refresh rates > 1s. I think this is because the application is much more busy with other things (several threads, computationally expensive numerical routines for on the fly data analysis, etc.). This seems to increase the chance for a race condition (but this is really over my head).
I should also point out, in our real application the error occurs maybe only once per hour. However, our data acquisition is often running over several days. Typically within 24h, the application crashes sue to the bug.
Indeed, he mini example code that I provided seems to behave differently. When the refresh rate is low, the issue seems to occur very rarely. Maybe if you run the example code for several hours the error will also show up. I must confess, I haven't checked that. Indeed, I simply set the refresh rate to this high value, so that you guys can see the error quickly.
I am very much hoping for a solution.
Many thanx and greetings, Helmut
from chaco.
Tested the following to resolve the issue (suggestion by Didrik).
In grid.py change the following lines
def _reset_cache(self):
""" Clears the cached tick positions.
"""
self._tick_positions = zeros((1,2), dtype=float) <--
#self._tick_positions = array([], dtype=float)
self._tick_extents = zeros((1, 2), dtype=float) <--
#self._tick_extents = array([], dtype=float)
self._cache_valid = False
return
On Linux, (Ubuntu natty) this does not solve the issue, however, the traceback is now different. See below.
ValueError Traceback (most recent call last)
/usr/lib/python2.7/dist-packages/enthought/enable/abstract_window.pyc in _paint(self, event)
348 self.component.do_layout()
349 gc = self._gc
--> 350 self.component.draw(gc, view_bounds=(0, 0, size[0], size[1]))
351
352 # damaged_regions = draw_result['damaged_regions']
/usr/lib/python2.7/dist-packages/enthought/enable/component.pyc in draw(self, gc, view_bounds, mode)
423 self.do_layout()
424
--> 425 self._draw(gc, view_bounds, mode)
426 return
427
/usr/lib/python2.7/dist-packages/enthought/enable/component.pyc in _draw(self, gc, view_bounds, mode)
759 else:
760 for layer in self.draw_order:
--> 761 self._dispatch_draw(layer, gc, view_bounds, mode)
762
763 return
/usr/lib/python2.7/dist-packages/enthought/enable/container.pyc in _dispatch_draw(self, layer, gc, view_bounds, mode)
308 my_handler = getattr(self, "draw_container" + layer, None)
309 if my_handler:
--> 310 my_handler(gc, view_bounds, mode)
311
312 # Now transform coordinates and draw the children
/usr/lib/python2.7/dist-packages/enthought/enable/container.pyc in _draw_container_underlay(self, gc, view_bounds, mode)
350
351 def _draw_container_underlay(self, gc, view_bounds=None, mode="normal"):
--> 352 self._draw_underlay(gc, view_bounds, mode)
353
354 def _draw_container_border(self, gc, view_bounds=None, mode="normal"):
/usr/lib/python2.7/dist-packages/enthought/enable/component.pyc in _draw_underlay(self, gc, view_bounds, mode)
876 # just overlays drawn at a different time in the rendering loop.
877 if underlay.visible:
--> 878 underlay.overlay(self, gc, view_bounds, mode)
879 return
880
/usr/lib/python2.7/dist-packages/enthought/chaco/grid.py in overlay(self, other_component, gc, view_bounds, mode)
304 return
305 self._compute_ticks(other_component)
--> 306 self._draw_component(gc, view_bounds, mode)
307 self._cache_valid = False
308 return
/usr/lib/python2.7/dist-packages/enthought/chaco/grid.py in _draw_component(self, gc, view_bounds, mode)
341 if self.orientation == "horizontal":
342 starts = self._tick_positions.copy()
--> 343 starts[:,0] = self._tick_extents[:,0]
344 ends = self._tick_positions.copy()
345 ends[:,0] = self._tick_extents[:,1]
ValueError: array dimensions are not compatible for copy
from chaco.
I today tested the Bugfix under Windows 7 Ultimate SP1 (64bit) installed with the latest enthought python distribution and received the following traceback of the error when running the code issue_9.py:
Die genaue Beschreibung der pythonversion ist:
Python 2-7.1 :EPD 7.0-2 (32-bit): (r271:86832,Dec 2 2010,10:35:02) [MSC v.1500 32 bit (Intel)]
I also tested the same version of python under Windows 7 (32 bit) and the same error/traceback occured.
ValueError Traceback (most recent call last)
C:\Python27\lib\site-packages\enthought\enable\abstract_window.py in _paint(self, event)
366 self.component.do_layout()
367 gc = self._gc
--> 368 self.component.draw(gc, view_bounds=(0, 0, size[0], size[1]))
369
370 # damaged_regions = draw_result['damaged_regions']
C:\Python27\lib\site-packages\enthought\enable\component.py in draw(self, gc, view_bounds, mode)
423 self.do_layout()
424
--> 425 self._draw(gc, view_bounds, mode)
426 return
427
C:\Python27\lib\site-packages\enthought\enable\component.py in _draw(self, gc, view_bounds, mode)
761 else:
762 for layer in self.draw_order:
--> 763 self._dispatch_draw(layer, gc, view_bounds, mode)
764
765 return
C:\Python27\lib\site-packages\enthought\enable\container.py in _dispatch_draw(self, layer, gc, view_bounds, mode)
308 my_handler = getattr(self, "draw_container" + layer, None)
309 if my_handler:
--> 310 my_handler(gc, view_bounds, mode)
311
312 # Now transform coordinates and draw the children
C:\Python27\lib\site-packages\enthought\enable\container.py in _draw_container_underlay(self, gc, view_bounds, mode)
350
351 def _draw_container_underlay(self, gc, view_bounds=None, mode="normal"):
--> 352 self._draw_underlay(gc, view_bounds, mode)
353
354 def _draw_container_border(self, gc, view_bounds=None, mode="normal"):
C:\Python27\lib\site-packages\enthought\enable\component.py in _draw_underlay(self, gc, view_bounds, mode)
878 # just overlays drawn at a different time in the rendering loop.
879 if underlay.visible:
--> 880 underlay.overlay(self, gc, view_bounds, mode)
881 return
882
C:\Python27\lib\site-packages\enthought\chaco\grid.py in overlay(self, other_component, gc, view_bounds, mode)
306 return
307 self._compute_ticks(other_component)
--> 308 self._draw_component(gc, view_bounds, mode)
309 self._cache_valid = False
310 return
C:\Python27\lib\site-packages\enthought\chaco\grid.py in _draw_component(self, gc, view_bounds, mode)
342 if self.orientation == "horizontal":
343 starts = self._tick_positions.copy()
--> 344 starts[:,0] = self._tick_extents[:,0]
345 ends = self._tick_positions.copy()
346 ends[:,0] = self._tick_extents[:,1]
ValueError: array dimensions are not compatible for copy
from chaco.
Today, I tested whether the issue still persists when using WXTimer instead of a thread.
The bug does not occur when using WXTimer (both ipython and bare python with wx app). A code snippet of the test is pasted below. This supports the previous idea that this bug is tightly related to multi threading. It suggests that setting the data of an ArrayPlotData from within a thread is not safe. The chain of events that is triggered by setting the data, is not finished before the data is set again. I think this is usually called a race condition, isn't it?
import threading
import numpy
from enthought.traits.api import SingletonHasTraits, Array, Instance
from enthought.traits.ui.api import View, Item, VSplit
from enthought.enable.api import Component, ComponentEditor
from enthought.chaco.api import ArrayPlotData, Plot
from enthought.pyface.timer.api import Timer
class IssueNineThread( SingletonHasTraits ):
"""Produces a bug in chaco."""
data = Array( value=numpy.zeros(100) )
def _data_changed(self):
self.plot_data.set_data('y', self.data)
plot_data = Instance( ArrayPlotData )
def _plot_data_default(self):
return ArrayPlotData(x=numpy.arange(100), y=self.data)
plot = Instance( Plot )
def _plot_default(self):
plot = Plot(self.plot_data, resizable='hv')
plot.plot(('x','y'), style='line', color='blue')
return plot
def start(self):
self.stop_request = threading.Event()
threading.Thread( target=self.run ).start()
def stop(self):
self.stop_request.set()
def run(self):
while True:
#self.stop_request.wait(0.001)
if self.stop_request.isSet():
break
#self.trait_set(True, data=self.data + numpy.random.random_integers(10, 100, 100))
self.data = self.data + numpy.random.random_integers(10, 100, 100)
traits_view = View(VSplit(Item('plot', editor=ComponentEditor(), show_label=False, resizable=True),
Item('none'),
),
)
class IssueNineWXTimer( SingletonHasTraits ):
"""No error is produced when using WX Timer."""
data = Array( value=numpy.zeros(100) )
def _data_changed(self):
self.plot_data.set_data('y', self.data)
plot_data = Instance( ArrayPlotData )
def _plot_data_default(self):
return ArrayPlotData(x=numpy.arange(100), y=self.data)
plot = Instance( Plot )
def _plot_default(self):
plot = Plot(self.plot_data, resizable='hv')
plot.plot(('x','y'), style='line', color='blue')
return plot
timer = Instance( Timer )
def start(self):
self.timer = Timer(0, self.update_data)
self.timer.Start()
def stop(self):
self.timer.Stop()
def update_data(self):
self.data = self.data + numpy.random.random_integers(10, 100, 100)
traits_view = View(Item('plot', editor=ComponentEditor(), show_label=False, resizable=True),)
if name == 'main':
import wx
#b = IssueNineWXTimer()
b = IssueNineThread()
b.edit_traits()
#"""
b.plot.value_range.low_setting = 0.0
b.plot.value_range.high_setting = 1e6
#"""
b.start()
wx.PySimpleApp().MainLoop()
from chaco.
Good find. Setting the ArrayPlotData causes a cascade of traits events which
could take some time. If you want to use threads, you should definitely use
locks.
Bryce
On Thu, Jun 30, 2011 at 1:47 PM, HelmutFedder <
[email protected]>wrote:
Today, I tested whether the issue still persists when using WXTimer instead
of a thread.The bug does not occur when using WXTimer (both ipython and bare python
with wx app). A code snippet of the test is pasted below. This supports the
previous idea that this bug is tightly related to multi threading. It
suggests that setting the data of an ArrayPlotData from within a thread is
not safe. The chain of events that is triggered by setting the data, is not
finished before the data is set again. I think this is usually called a race
condition, isn't it?import threading
import numpyfrom enthought.traits.api import SingletonHasTraits, Array, Instance
from enthought.traits.ui.api import View, Item, VSplit
from enthought.enable.api import Component, ComponentEditor
from enthought.chaco.api import ArrayPlotData, Plot
from enthought.pyface.timer.api import Timerclass IssueNineThread( SingletonHasTraits ):
"""Produces a bug in chaco."""
data = Array( value=numpy.zeros(100) )
def _data_changed(self):
self.plot_data.set_data('y', self.data)plot_data = Instance( ArrayPlotData )
def _plot_data_default(self):
return ArrayPlotData(x=numpy.arange(100), y=self.data)plot = Instance( Plot )
def _plot_default(self):
plot = Plot(self.plot_data, resizable='hv')
plot.plot(('x','y'), style='line', color='blue')
return plotdef start(self):
self.stop_request = threading.Event()
threading.Thread( target=self.run ).start()def stop(self):
self.stop_request.set()def run(self):
while True:
#self.stop_request.wait(0.001)
if self.stop_request.isSet():
break
#self.trait_set(True, data=self.data +
numpy.random.random_integers(10, 100, 100))
self.data = self.data + numpy.random.random_integers(10, 100,
100)traits_view = View(VSplit(Item('plot', editor=ComponentEditor(),
show_label=False, resizable=True),
Item('none'),
),
)class IssueNineWXTimer( SingletonHasTraits ):
"""No error is produced when using WX Timer."""
data = Array( value=numpy.zeros(100) )
def _data_changed(self):
self.plot_data.set_data('y', self.data)plot_data = Instance( ArrayPlotData )
def _plot_data_default(self):
return ArrayPlotData(x=numpy.arange(100), y=self.data)plot = Instance( Plot )
def _plot_default(self):
plot = Plot(self.plot_data, resizable='hv')
plot.plot(('x','y'), style='line', color='blue')
return plottimer = Instance( Timer )
def start(self):
self.timer = Timer(0, self.update_data)
self.timer.Start()def stop(self):
self.timer.Stop()def update_data(self):
self.data = self.data + numpy.random.random_integers(10, 100, 100)traits_view = View(Item('plot', editor=ComponentEditor(),
show_label=False, resizable=True),)if name == 'main':
import wx
#b = IssueNineWXTimer()
b = IssueNineThread()
b.edit_traits()
#"""
b.plot.value_range.low_setting = 0.0
b.plot.value_range.high_setting = 1e6
#"""
b.start()
wx.PySimpleApp().MainLoop()Reply to this email directly or view it on GitHub:
#9 (comment)
from chaco.
Dear Bryce,
Many thanks for your insight.
please apologize the late response - too much work.
OK, I am confused now. I believe 'traits' should somehow take care about this and be in a sense 'thread safe', because: if updating a plot can result in a race condition, can't any setting of a trait attribute, say a large array, do so too? Or is a race condition usually just so unlikely that it won't happen in a lifetime? If there can be problems under other circumstances, too, how can I judge whether it is safe to set a trait attribute out of a thread?
Yes, I also thought to use locks, previously, but how? I can acquire a lock before I set the array and release it afterwards. But then, to do something useful, I guess the event handler in the main thread / GUI thread has to acquire the lock as well. How to do that?
Does that mean, every application that has a plot and a thread that delivers the data should use locks?
Cheers, Helmut
from chaco.
Traits isn't threadsafe by default. You can optionally set a value in the UI
thread, which may be enough for you if you always set the chaco data in the
UI thread.
https://svn.enthought.com/enthought/wiki/OnTraitChangeDispatch
Bryce
On Wed, Jul 6, 2011 at 1:49 AM, HelmutFedder <
[email protected]>wrote:
Dear Bryce,
Many thanks for your insight.
please apologize the late response - too much work.
OK, I am confused now. I believe 'traits' should somehow take care about
this and be in a sense 'thread safe', because: if updating a plot can result
in a race condition, can't any setting of a trait attribute, say a large
array, do so too? Or is a race condition usually just so unlikely that it
won't happen in a lifetime? If there can be problems under other
circumstances, too, how can I judge whether it is safe to set a trait
attribute out of a thread?Yes, I also thought to use locks, previously, but how? I can acquire a lock
before I set the array and release it afterwards. But then, to do something
useful, I guess the event handler in the main thread / GUI thread has to
acquire the lock as well. How to do that?Does that mean, every application that has a plot and a thread that
delivers the data should use locks?Cheers, Helmut
Reply to this email directly or view it on GitHub:
#9 (comment)
from chaco.
Ah, this looks promising!
I did a first test and it seems it solves the problem
It is a bit tricky to test, because in the sample code, the refresh rate needs to be very high to produce the bug. With high refresh rate and dispatch='ui', the ui can freeze. So you need to play a bit with the refresh rate, until you find a value hiigh enough such that the bug is produced with dispatch='same' and low enough such that the ui stays active with dispatch='ui'.
We will do more testing on the real code within the next days.
Tentatively, this solves the issue.
I think the dispatch parameter definitely deserves more explanation in the documentation. Maybe, for now, you can just put a note with a link to the site that you sent me.
Thanks and many greetings,
Helmut
from chaco.
We have done some more testing.
Our application has now been running for >24h under windows XP as well as ubuntu without a crash. It looks like this indeed resolves the issue as well as issue #8.
Please give us some time for testing and go ahead and close this issue if you don't hear from us within the next few weeks.
Since threading is so important in many scientific applications, I do think the documentation deserves a chapter 'traits and multi threading' or something similar.
Thanks and many greetings,
Helmut
from chaco.
Yup, I agree completely. Now we just have to find someone willing to write
that chapter :) I have brought up the issue of porting the old wiki docs
into the Traits documentation, hopefully someone with some free time can
address it.
Bryce
On Mon, Jul 11, 2011 at 3:36 PM, HelmutFedder <
[email protected]>wrote:
We have done some more testing.
Our application has now been running for >24h under windows XP as well as
ubuntu without a crash. It looks like this indeed resolves the issue as well
as issue #8.Please give us some time for testing and go ahead and close this issue if
you don't hear from us within the next few weeks.Since threading is so important in many scientific applications, I do think
the documentation deserves a chapter 'traits and multi threading' or
something similar.Thanks and many greetings,
Helmut
Reply to this email directly or view it on GitHub:
#9 (comment)
from chaco.
Just stumbled upon this issue too, as well as related issue #8. I was already vaguely aware that TraitsUI wasn't completely thread safe, but I feel that simply setting an ArrayPlotData really should be otherwise the abstraction is getting a bit too leaky.
from chaco.
Related Issues (20)
- ImportError: cannot import name 'encodestring' from 'base64
- TypeError: 'float' object cannot be interpreted as an integer when running python chaco/examples/demo/advanced/spec_waterfall.py
- fft error in spec_waterfall example HOT 1
- NameError: name 'gc' is not defined
- ImportError: attempted relative import with no known parent package
- ImportError: cannot import name 'BaseTool' from 'chaco.api' HOT 1
- file not found for capitol.jpg when running examples/user_guide/plot_types/create_plot_snapshots.py
- gc reference before construction when running chaco.chaco.plots.polar_line_renderer.py HOT 1
- ModuleNotFoundError: No module named 'pyface.ui.qt4.color' when running demos related to enable/enable/trait_defs/ui/qt4/rgba_color_editor.py HOT 2
- ImportError: cannot import name 'encodestring' from 'base64' HOT 1
- traits.trait_errors.TraitError: Cannot set the undefined 'format' attribute of a 'RangeEditor' object. when running chaco/chaco/examples/demo/nonlinear_color_mapping.py HOT 1
- ValueError: Handler.init() must return True or False, but instead returned None. when running chaco/chaco/examples/demo/basic/image_from_file.py HOT 1
- ValueError: object of too small depth for desired array when running chaco/chaco/examples/demo/advanced/scalar_image_function_inspector.py HOT 1
- NotImplementedError when running examples/demo/updating_plot/updating_plot1.py HOT 1
- Better handling of "Dark Mode"
- DataView/Plot `bgcolor` can't be tuple
- Cython 3.0 breaks Kiva builds HOT 1
- Chaco 6.0.0 installation failed with Numpy 1.26.4 HOT 8
- Missing f-string in logger warning
- Typo in base_2d_plot.py
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from chaco.